diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6e470660bed4db8b05295a49f6300f19aadf00cc --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +log/ + +*.class +*/target/ + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +/.idea/ +*.iml + +*.DS_Store + +node_modules +/admin/src/main/resources/static diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6b63cdd70323f80fe5600b9f7993020cfed22320..de5a3c51e245f629b9ab3473f8340f2c539e1922 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,6 +61,8 @@ build_dev: - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" only: - dev + when: manual + deploy_master: @@ -102,6 +104,7 @@ deploy_dev: url: https://dataportal-dev.edirex.ics.muni.cz/ only: - dev + when: manual build_tags: diff --git a/README.md b/README.md index ee13a8700ab1b127078ce42fa005ff30b4774534..570d43bf080a4196b5a9e874cd19017062ca3309 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,3 @@ https://dataportal.europdx.eu -IDE TO diff --git a/admin/.classpath b/admin/.classpath deleted file mode 100644 index 39abf1c5e9102a46b2af14da5d6d536eb2cd121a..0000000000000000000000000000000000000000 --- a/admin/.classpath +++ /dev/null @@ -1,49 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" output="target/classes" path="src/main/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" output="target/test-classes" path="src/test/java"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - <attribute name="test" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> - <attributes> - <attribute name="maven.pomderived" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" path="target/generated-sources/annotations"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - <attribute name="ignore_optional_problems" value="true"/> - <attribute name="m2e-apt" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations"> - <attributes> - <attribute name="optional" value="true"/> - <attribute name="maven.pomderived" value="true"/> - <attribute name="ignore_optional_problems" value="true"/> - <attribute name="m2e-apt" value="true"/> - <attribute name="test" value="true"/> - </attributes> - </classpathentry> - <classpathentry kind="output" path="target/classes"/> -</classpath> diff --git a/admin/.factorypath b/admin/.factorypath deleted file mode 100644 index d25b2f384001e995e6f0a52be9e1c83366e75dee..0000000000000000000000000000000000000000 --- a/admin/.factorypath +++ /dev/null @@ -1,110 +0,0 @@ -<factorypath> - <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.8.10/jackson-core-2.8.10.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/dataformat/jackson-dataformat-csv/2.8.10/jackson-dataformat-csv-2.8.10.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.8.10/jackson-databind-2.8.10.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-web/1.5.8.RELEASE/spring-boot-starter-web-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter/1.5.8.RELEASE/spring-boot-starter-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-logging/1.5.8.RELEASE/spring-boot-starter-logging-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/ch/qos/logback/logback-core/1.1.11/logback-core-1.1.11.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/log4j-over-slf4j/1.7.25/log4j-over-slf4j-1.7.25.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-tomcat/1.5.8.RELEASE/spring-boot-starter-tomcat-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/embed/tomcat-embed-core/8.5.23/tomcat-embed-core-8.5.23.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/tomcat-annotations-api/8.5.23/tomcat-annotations-api-8.5.23.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/embed/tomcat-embed-el/8.5.23/tomcat-embed-el-8.5.23.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/tomcat/embed/tomcat-embed-websocket/8.5.23/tomcat-embed-websocket-8.5.23.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-web/4.3.12.RELEASE/spring-web-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-aop/4.3.12.RELEASE/spring-aop-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-beans/4.3.12.RELEASE/spring-beans-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-context/4.3.12.RELEASE/spring-context-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-webmvc/4.3.12.RELEASE/spring-webmvc-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-expression/4.3.12.RELEASE/spring-expression-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-thymeleaf/1.5.8.RELEASE/spring-boot-starter-thymeleaf-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/thymeleaf/thymeleaf-spring4/3.0.2.RELEASE/thymeleaf-spring4-3.0.2.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/thymeleaf/thymeleaf/3.0.2.RELEASE/thymeleaf-3.0.2.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/attoparser/attoparser/2.0.1.RELEASE/attoparser-2.0.1.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/unbescape/unbescape/1.1.4.RELEASE/unbescape-1.1.4.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/nz/net/ultraq/thymeleaf/thymeleaf-layout-dialect/2.1.1/thymeleaf-layout-dialect-2.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/codehaus/groovy/groovy/2.4.12/groovy-2.4.12.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/nz/net/ultraq/thymeleaf/thymeleaf-expression-processor/1.1.2/thymeleaf-expression-processor-1.1.2.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-actuator/1.5.8.RELEASE/spring-boot-starter-actuator-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-actuator/1.5.8.RELEASE/spring-boot-actuator-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/bootstrap/3.3.7/bootstrap-3.3.7.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/jquery/1.11.1/jquery-1.11.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/font-awesome/4.7.0/font-awesome-4.7.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/animate.css/3.5.2/animate.css-3.5.2.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/bower/amcharts3/3.21.3/amcharts3-3.21.3.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/webjars-locator/0.32-1/webjars-locator-0.32-1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/webjars/webjars-locator-core/0.32/webjars-locator-core-0.32.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/commons/commons-compress/1.9/commons-compress-1.9.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-starter-data-neo4j/1.5.8.RELEASE/spring-boot-starter-data-neo4j-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/data/spring-data-neo4j/4.2.8.RELEASE/spring-data-neo4j-4.2.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-tx/4.3.12.RELEASE/spring-tx-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/slf4j/jcl-over-slf4j/1.7.25/jcl-over-slf4j-1.7.25.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/data/spring-data-commons/1.13.8.RELEASE/spring-data-commons-1.13.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-ogm-core/2.1.5/neo4j-ogm-core-2.1.5.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-ogm-api/2.1.5/neo4j-ogm-api-2.1.5.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/commons-codec/commons-codec/1.10/commons-codec-1.10.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-ogm-compiler/2.1.5/neo4j-ogm-compiler-2.1.5.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/commons/commons-collections4/4.1/commons-collections4-4.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-ogm-http-driver/2.1.5/neo4j-ogm-http-driver-2.1.5.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/httpcomponents/httpcore/4.4.8/httpcore-4.4.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/spring-core/4.3.12.RELEASE/spring-core-4.3.12.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-devtools/1.5.8.RELEASE/spring-boot-devtools-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot/1.5.8.RELEASE/spring-boot-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/springframework/boot/spring-boot-autoconfigure/1.5.8.RELEASE/spring-boot-autoconfigure-1.5.8.RELEASE.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j/3.1.1/neo4j-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-kernel/3.1.1/neo4j-kernel-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-graphdb-api/3.1.1/neo4j-graphdb-api-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-resource/3.1.1/neo4j-resource-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-common/3.1.1/neo4j-common-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-collections/3.1.1/neo4j-collections-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-primitive-collections/3.1.1/neo4j-primitive-collections-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-unsafe/3.1.1/neo4j-unsafe-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-io/3.1.1/neo4j-io-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-csv/3.1.1/neo4j-csv-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-logging/3.1.1/neo4j-logging-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-lucene-upgrade/3.1.1/neo4j-lucene-upgrade-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/lucene/lucene-backward-codecs/5.5.0/lucene-backward-codecs-5.5.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-lucene-index/3.1.1/neo4j-lucene-index-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/lucene/lucene-analyzers-common/5.5.0/lucene-analyzers-common-5.5.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/lucene/lucene-core/5.5.0/lucene-core-5.5.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/lucene/lucene-queryparser/5.5.0/lucene-queryparser-5.5.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/apache/lucene/lucene-codecs/5.5.0/lucene-codecs-5.5.0.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-graph-algo/3.1.1/neo4j-graph-algo-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-udc/3.1.1/neo4j-udc-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-graph-matching/3.1.1/neo4j-graph-matching-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher/3.1.1/neo4j-cypher-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/scala-lang/scala-library/2.11.8/scala-library-2.11.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/scala-lang/scala-reflect/2.11.8/scala-reflect-2.11.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-codegen/3.1.1/neo4j-codegen-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/ow2/asm/asm/5.0.4/asm-5.0.4.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-compiler-2.3/2.3.8/neo4j-cypher-compiler-2.3-2.3.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-frontend-2.3/2.3.8/neo4j-cypher-frontend-2.3-2.3.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/googlecode/concurrentlinkedhashmap/concurrentlinkedhashmap-lru/1.4.2/concurrentlinkedhashmap-lru-1.4.2.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-compiler-3.0/3.0.8/neo4j-cypher-compiler-3.0-3.0.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-frontend-3.0/3.0.8/neo4j-cypher-frontend-3.0-3.0.8.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-compiler-3.1/3.1.1/neo4j-cypher-compiler-3.1-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-cypher-frontend-3.1/3.1.1/neo4j-cypher-frontend-3.1-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/github/ben-manes/caffeine/caffeine/2.3.5/caffeine-2.3.5.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/parboiled/parboiled-scala_2.11/1.1.7/parboiled-scala_2.11-1.1.7.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/parboiled/parboiled-core/1.1.7/parboiled-core-1.1.7.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/net/sf/opencsv/opencsv/2.3/opencsv-2.3.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-jmx/3.1.1/neo4j-jmx-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-consistency-check/3.1.1/neo4j-consistency-check-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-command-line/3.1.1/neo4j-command-line-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-dbms/3.1.1/neo4j-dbms-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/neo4j/neo4j-import-tool/3.1.1/neo4j-import-tool-3.1.1.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/hibernate/hibernate-validator/5.3.5.Final/hibernate-validator-5.3.5.Final.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/org/jboss/logging/jboss-logging/3.3.1.Final/jboss-logging-3.3.1.Final.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/fasterxml/classmate/1.3.4/classmate-1.3.4.jar" enabled="true" runInBatchMode="false"/> - <factorypathentry kind="VARJAR" id="M2_REPO/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar" enabled="true" runInBatchMode="false"/> -</factorypath> diff --git a/admin/.project b/admin/.project deleted file mode 100644 index 15234ef54b41dbb4ee4fc41fabf8f13f39fa1f76..0000000000000000000000000000000000000000 --- a/admin/.project +++ /dev/null @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>admin</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.m2e.core.maven2Builder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - <nature>org.eclipse.m2e.core.maven2Nature</nature> - </natures> -</projectDescription> diff --git a/admin/pom.xml b/admin/pom.xml index da7175127267102dc300f1ba7eea6ef9b8b08819..e215943e308a687e1c0c5ca73f2015ecfb901335 100644 --- a/admin/pom.xml +++ b/admin/pom.xml @@ -24,6 +24,7 @@ <groupId>org.pdxfinder</groupId> <artifactId>data-services</artifactId> </dependency> + <dependency> <groupId>org.pdxfinder</groupId> <artifactId>data-model</artifactId> @@ -39,80 +40,22 @@ <artifactId>spring-boot-starter-actuator</artifactId> </dependency> - <!--<dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-thymeleaf</artifactId> - </dependency> - - <dependency> - <groupId>org.webjars</groupId> - <artifactId>bootstrap</artifactId> - <version>3.3.7</version> - </dependency> - <dependency> - <groupId>org.webjars</groupId> - <artifactId>font-awesome</artifactId> - <version>4.7.0</version> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-bolt-driver</artifactId> + <version>3.1.20</version> </dependency> <dependency> - <groupId>org.webjars</groupId> - <artifactId>animate.css</artifactId> - <version>3.5.2</version> + <!-- WARNING, do not update db engine (stable: 1.4.197) cause compatibility issues, see https://github.com/h2database/h2database/issues/2078 --> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>1.4.197</version> </dependency> - - <dependency> - <groupId>org.webjars.bower</groupId> - <artifactId>amcharts3</artifactId> - <version>3.21.3</version> - </dependency> - - <dependency> - <groupId>org.webjars</groupId> - <artifactId>webjars-locator</artifactId> - </dependency>--> - </dependencies> <build> <plugins> - <!--<plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>exec-maven-plugin</artifactId> - <version>1.6.0</version> - <executions> - <execution> - <id>install-dependencies</id> - <phase>validate</phase> - <goals> - <goal>exec</goal> - </goals> - <configuration> - <executable>${npm.executable}</executable> - <workingDirectory>src/main/app-ui</workingDirectory> - <arguments> - <argument>install</argument> - </arguments> - </configuration> - </execution> - <execution> - <id>build-angular-app</id> - <phase>validate</phase> - <goals> - <goal>exec</goal> - </goals> - <configuration> - <executable>ng</executable> - <workingDirectory>src/main/app-ui</workingDirectory> - <arguments> - <argument>build</argument> - </arguments> - </configuration> - </execution> - </executions> - - </plugin>--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> @@ -127,21 +70,4 @@ </plugins> </build> - <!-- Windows requires different command line --> - <!--<profiles> - <profile> - <id>platform-windows</id> - <activation> - <os> - <family>windows</family> - </os> - </activation> - <properties> - <npm.executable>npm.cmd</npm.executable> - <grunt.executable>grunt.cmd</grunt.executable> - <bower.executable>bower.cmd</bower.executable> - </properties> - </profile> - </profiles>--> - </project> diff --git a/admin/src/main/app-ui/package-lock.json b/admin/src/main/app-ui/package-lock.json index bd21e67a31740299de89eb6f4c46c68e8fb8c009..1cee6d41766e1c750d1fffff019529143e1a2409 100644 --- a/admin/src/main/app-ui/package-lock.json +++ b/admin/src/main/app-ui/package-lock.json @@ -9941,7 +9941,8 @@ }, "ws": { "version": "1.1.2", - "resolved": "", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", + "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", "dev": true, "requires": { "options": ">=0.0.5", diff --git a/admin/src/main/app-ui/src/app/datasource-specific/datasource-specific.component.html b/admin/src/main/app-ui/src/app/datasource-specific/datasource-specific.component.html index 5baf9aa71b0845d5d9eb3e7cb7df41611894c9eb..ff946ccbae1d5dcee75723607f9049ac8989cfd6 100644 --- a/admin/src/main/app-ui/src/app/datasource-specific/datasource-specific.component.html +++ b/admin/src/main/app-ui/src/app/datasource-specific/datasource-specific.component.html @@ -58,51 +58,6 @@ -<div class="wrapper wrapper-content animated fadeInRight"> - <div class="p-w-md m-t-sm col-lg-10 col-lg-offset-1"> - - <div class="row" style="margin-top: -10px;"> - - <div class="col-lg-12" *ngIf="dataExists"> - - <form #mappingForm="ngForm" (ngSubmit)="updateMappingEntity()" novalidate> - <div class="pdxfinder float-e-margins" style="border: 1px solid rgba(3, 54, 157, 1);"> - - - <div class="pdxfinder-content pdxfinder-heading"> - <h3><i class="ti-agenda"></i> <span style="color: #03369D"> {{dataSource | uppercase}} </span> Mapping </h3> - <small><i class="fa fa-tim"></i> You have 70 unmapped ... and 16 orphaned ...</small> - - - <button *ngIf="report == null" style="float: right; margin-top:-30px;" class="btn btn-primary btn-sm" type="submit"> - <i class="ti-cloud-up"></i> Submit Curation - </button> - - </div> - - <div class="pdxfinder-content"> - - <div *ngIf="report == 'success'" class="alert alert-success alert-dismissable"> - <a aria-hidden="true" class="close" type="button" (click)="toggleReport('success')">Ă—</a> - Success: <em> The submitted curation was successful, Clear off notification to continue </em> <a class="alert-link"> ... </a>. - </div> - - <div *ngIf="report == 'failed'" class="alert alert-danger alert-dismissable"> - <a aria-hidden="true" class="close" type="button" (click)="toggleReport(null)">Ă—</a> - OOps!! <em> Failed Request: The submitted curation is invalid, Clear off notification to continue </em> <a class="alert-link"> ... </a>. - </div> - - -<div class="wrapper wrapper-content animated fadeInRight"> - <div class="p-w-md m-t-sm col-lg-10 col-lg-offset-1"> - - <div class="row" style="margin-top: -10px;"> - - <div class="col-lg-12" *ngIf="dataExists"> - - <form #mappingForm="ngForm" (ngSubmit)="updateMappingEntity()" novalidate> - <div class="pdxfinder float-e-margins" style="border: 1px solid rgba(3, 54, 157, 1);"> - <div class="wrapper wrapper-content animated fadeInRight"> @@ -274,4 +229,4 @@ <td> {{ mapping.mappingValues.OriginTissue | uppercase }} </td> --> <!-- <a [routerLink]="['../'+count]"> {{count }} </a> -<a [routerLink]="['../']" [queryParams]="{page: count}" > {{count }} </a> {{'curation/'+entityTypeUrl+'/'+dataSource}} +'?page='+count --> +<a [routerLink]="['../']" [queryParams]="{page: count}" > {{count }} </a> {{'curation/'+entityTypeUrl+'/'+dataSource}} +'?page='+count --> \ No newline at end of file diff --git a/admin/src/main/app-ui/src/app/datasource-summary/datasource-summary.component.html b/admin/src/main/app-ui/src/app/datasource-summary/datasource-summary.component.html index 2baa7f8c8dbab5aad30e5d718feb49e5fc24f6a4..ae0c6cd6870be46ccfa6e80d9913f843c7a7cde6 100644 --- a/admin/src/main/app-ui/src/app/datasource-summary/datasource-summary.component.html +++ b/admin/src/main/app-ui/src/app/datasource-summary/datasource-summary.component.html @@ -135,4 +135,4 @@ </div> </div> -<!-- use container or blank for small screen and col-lg-10 col-lg-offset-1 for 17 inches upwards swing tada wobble bounceIn (Up,Left,Right,Down) lightSpeedIn , flipInY, rotateInDownRight, rotateInUpLeft, slideInLeft, hinge, rollIn--> +<!-- use container or blank for small screen and col-lg-10 col-lg-offset-1 for 17 inches upwards swing tada wobble bounceIn (Up,Left,Right,Down) lightSpeedIn , flipInY, rotateInDownRight, rotateInUpLeft, slideInLeft, hinge, rollIn--> \ No newline at end of file diff --git a/admin/src/main/app-ui/src/app/mapping.service.ts b/admin/src/main/app-ui/src/app/mapping.service.ts index bb5eaf3353bc4a03b682c93d88235c548bd32668..b62f5e615ab4b2a0b926e7ec27392b46e6558c01 100644 --- a/admin/src/main/app-ui/src/app/mapping.service.ts +++ b/admin/src/main/app-ui/src/app/mapping.service.ts @@ -172,61 +172,11 @@ export class MappingService { - pushFileToStorage(file: File, entityType: string): Observable<HttpEvent<{}>> { - - const formdata: FormData = new FormData(); - formdata.append('uploads', file); - - const url = `${this._uploadURL}?entity-type=${entityType}`; - - return this.http.post<any>(url, formdata) - .pipe( - catchError(this.errorHandler) - ); - - } - - - - connectToDataFlow() { - - return fetch('http://localhost:8081/api/mapping/diagnosis?ds=JAX') - .then((res) => res.json()) - .then((data) => data) - .catch(error => console.log(error)); - } - - - - pushFileToStorage(file: File, entityType: string): Observable<HttpEvent<{}>> { - - const formdata: FormData = new FormData(); - formdata.append('uploads', file); - - const url = `${this._uploadURL}?entity-type=${entityType}`; - - return this.http.post<any>(url, formdata) - .pipe( - catchError(this.errorHandler) - ); - - } - - +} - connectToDataFlow() { - return fetch('http://localhost:8081/api/mapping/diagnosis?ds=JAX') - .then((res) => res.json()) - .then((data) => data) - .catch(error => console.log(error)); - } - - - -} diff --git a/admin/src/main/app-ui/src/pdxfinder/pattern-library/style.css b/admin/src/main/app-ui/src/pdxfinder/pattern-library/style.css index f1347e48fe0dcf2e21c95c3ddf525ee8f5f3c0f4..99a665cbcf07918c79d200458f030e5d371b1a76 100755 --- a/admin/src/main/app-ui/src/pdxfinder/pattern-library/style.css +++ b/admin/src/main/app-ui/src/pdxfinder/pattern-library/style.css @@ -4304,3 +4304,9 @@ a.compose-mail { margin-bottom: 5px; margin-right: 5px; } + + + + + + diff --git a/admin/src/main/java/org/pdxfinder/controllers/AjaxController.java b/admin/src/main/java/org/pdxfinder/controllers/AjaxController.java index 0dea840bf01b241cd504d36c7d346e5a08027b88..b534ba22dc6605ad973acf7dbd31212ba6384417 100644 --- a/admin/src/main/java/org/pdxfinder/controllers/AjaxController.java +++ b/admin/src/main/java/org/pdxfinder/controllers/AjaxController.java @@ -5,11 +5,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; import org.pdxfinder.rdbms.dao.MappingEntity; -import org.pdxfinder.services.zooma.ZoomaEntity; import org.pdxfinder.services.MappingService; import org.pdxfinder.services.UtilityService; import org.pdxfinder.services.dto.PaginationDTO; import org.pdxfinder.services.mapping.CSVHandler; +import org.pdxfinder.services.zooma.ZoomaEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -20,6 +20,7 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.*; @@ -127,7 +128,7 @@ public class AjaxController { * Bulk update of Records */ @PutMapping("/mappings") - public ResponseEntity<?> editListOfEntityMappings(@RequestBody List<MappingEntity> submittedEntities) { + public ResponseEntity<?> editListOfEntityMappings(@RequestBody List<MappingEntity> submittedEntities) throws IOException { List data = mapper.convertValue(submittedEntities, List.class); log.info(data.toString()); diff --git a/admin/src/main/java/org/pdxfinder/controllers/TransController.java b/admin/src/main/java/org/pdxfinder/controllers/TransController.java index a01e6d3a044cad360d3f1cf8069836710afebe3b..3e9bac98755916b7b299326b54c5e94eca38d6a2 100644 --- a/admin/src/main/java/org/pdxfinder/controllers/TransController.java +++ b/admin/src/main/java/org/pdxfinder/controllers/TransController.java @@ -1,21 +1,21 @@ package org.pdxfinder.controllers; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; import org.pdxfinder.rdbms.dao.MappingEntity; -import org.pdxfinder.rdbms.repositories.MappingEntityRepository; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.TransformerService; import org.pdxfinder.rdbms.dao.PdmrPdxInfo; import org.pdxfinder.rdbms.dao.PdxInfo; +import org.pdxfinder.rdbms.repositories.MappingEntityRepository; +import org.pdxfinder.services.TransformerService; +import org.pdxfinder.services.UtilityService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @@ -33,6 +33,8 @@ public class TransController { private final static Logger log = LoggerFactory.getLogger(TransController.class); private String homeDir = System.getProperty("user.home"); + private String pdmrRawFileDir = homeDir + "/finderroot/data/PDMR/raw/"; + private RestTemplate restTemplate = new RestTemplate(); private ObjectMapper mapper = new ObjectMapper(); private TransformerService transformerService; @@ -42,16 +44,16 @@ public class TransController { private MappingEntityRepository mappingEntityRepository; - - public TransController(TransformerService transformerService, RestTemplateBuilder restTemplateBuilder){ + public TransController(TransformerService transformerService, RestTemplateBuilder restTemplateBuilder) { this.transformerService = transformerService; this.restTemplate = restTemplateBuilder.build(); + + this.transformerService.setDataRootDir(System.getProperty("user.home") + "/finderroot/data"); } @GetMapping("/view-data") - public PdxInfo getAllPdmr() - { + public PdxInfo getAllPdmr() { List<PdmrPdxInfo> pdmrPdxInfos = transformerService.getAllPdmr(); PdxInfo pdxInfo = new PdxInfo(); @@ -62,13 +64,12 @@ public class TransController { @GetMapping("/drugs") - public String getAllPdmrDrugs() - { + public String getAllPdmrDrugs() { List<PdmrPdxInfo> pdmrPdxInfos = transformerService.getAllPdmr(); String drugList = ""; - for (PdmrPdxInfo pdmrPdxInfo : pdmrPdxInfos){ + for (PdmrPdxInfo pdmrPdxInfo : pdmrPdxInfos) { drugList += transformerService.getDrugs(pdmrPdxInfo); } @@ -77,119 +78,52 @@ public class TransController { } - @GetMapping("/transform-pdmr-data") - public Object connectPdmr(){ + public Object connectPdmr() { List<Map<String, String>> mappingList = transformerService.transformDataAndSave(); return mappingList; } - /* - Test Saving Mapping Entity in H2 Database */ - - @GetMapping("/mapping") - public List<MappingEntity> saveMapping(){ - - ArrayList<String> mappingLabels = new ArrayList<>(); - mappingLabels.add("DataSource"); - mappingLabels.add("SampleDiagnosis"); - mappingLabels.add("TumorType"); - mappingLabels.add("OriginTissue"); - - Map mappingValues = new HashMap(); - mappingValues.put("OriginTissue","blood"); - mappingValues.put("TumorType","primary"); - mappingValues.put("SampleDiagnosis","acute myeloid leukemia"); - mappingValues.put("DataSource","jax"); - - MappingEntity mappingEntity = new MappingEntity("DIAGNOSIS", mappingLabels, mappingValues); - - mappingEntity.setMappedTermLabel("Acute Myeloid Leukemia"); - mappingEntity.setStatus("Created"); - mappingEntity.setDateCreated(new Date()); - mappingEntity.setMappedTermUrl("http://purl.obolibrary.org/obo/NCIT_C3171"); - mappingEntity.setMapType("direct"); - mappingEntity.setJustification("0"); - - //mappingEntityRepository.save(mappingEntity); - - return mappingEntityRepository.findAll(); - - } - @GetMapping("/get-mapping") - public List<MappingEntity> getMapping(){ + public List<MappingEntity> getMapping() { return mappingEntityRepository.findAll(); } + @RequestMapping(path = "/pdmr/genomics", method = RequestMethod.GET) + public Object transformPdmrGenomicData() { - @RequestMapping("/rewrite-pdmr-omic-data") - public Object downloads() { - - String omicFile= System.getProperty("user.home") + "/Downloads/NGS-LOADER/ncicancergenepaneldata_MARCH2019.csv"; + List transformedData = transformerService.transformOncoKB(); - List<Map<String, String>> dataList = utilityService.serializeCSVToMaps(omicFile); - - - List removedList = new ArrayList(); - for (Map<String, String> data : dataList) { + String destination = pdmrRawFileDir + "transformed-nci-gene-panel.csv"; - if ( !data.get("Sample_ID").equals("ORIGINATOR") ){ + utilityService.writeCsvFileGenerics(transformedData, destination); - String modelID = data.get("Model_ID"); - String sampleID = data.get("Sample_ID"); - - String passage = transformerService.getPassageByModelIDAndSampleID(modelID, sampleID); - - data.put("Passage", passage); - - /*if (passage.equals("XXXX")){ - removedList.add(data); - }*/ - } - - - if ( data.get("hgnc_symbol").equals("None Found") ){ - - removedList.add(data); - } - - } - - dataList.removeAll(removedList); - - - String destination = homeDir+"/Downloads/data.csv"; - utilityService.writeCsvFile(dataList, destination); - - return dataList; + return transformedData; } - @RequestMapping("/rewrite-ircc-cna-to-json") public Object irccCNA() { // Get CNA xls Template - String cnaFile = System.getProperty("user.home") + "/PDXFinder/data/IRCC-CRC/cna/CNA- IRCC-CRC template.xlsx"; + String cnaFile = homeDir + "/PDXFinder/data/IRCC-CRC/cna/CNA- IRCC-CRC template.xlsx"; - List<Map<String, String>> dataList = utilityService.serializeExcelDataNoIterator(cnaFile,0,1); + List<Map<String, String>> dataList = utilityService.serializeExcelDataNoIterator(cnaFile, 0, 1); return dataList; } - @RequestMapping("/rewrite-ircc-json") public Object irccTransformJson() { - String jsonFile= System.getProperty("user.home") + "/PDXFinder/data/IRCC-CRC/mut/old.json"; + String jsonFile = homeDir + "/PDXFinder/data/IRCC-CRC/mut/old.json"; List<Map<String, String>> dataList = (List) utilityService.serializeJSONToMaps(jsonFile, "IRCCVariation"); List<Map<String, String>> newDataList = new ArrayList<>(); @@ -206,9 +140,9 @@ public class TransController { newData.put("Model_ID", data.get("Model ID")); newData.put("Sample_ID", specimenId); - if ( specimenId.startsWith(modelId+"H") ){ + if (specimenId.startsWith(modelId + "H")) { newData.put("sample_origin", "patient tumor"); - } else if (specimenId.startsWith(modelId+"X")){ + } else if (specimenId.startsWith(modelId + "X")) { newData.put("sample_origin", "Xenograft"); } @@ -237,91 +171,80 @@ public class TransController { } - // Get Exome Template - String exomeFile = System.getProperty("user.home") + "/PDXFinder/data/IRCC-CRC/exome_IRCC-CRC template.xlsx"; + String exomeFile = homeDir + "/PDXFinder/data/IRCC-CRC/exome_IRCC-CRC template.xlsx"; - List<Map<String, String>> dataList2 = utilityService.serializeExcelDataNoIterator(exomeFile,0,1); + List<Map<String, String>> dataList2 = utilityService.serializeExcelDataNoIterator(exomeFile, 0, 1); return ListUtils.union(dataList2, newDataList); } - - - - @RequestMapping("/rewrite-curie-lc-cna") public Object curieTransform() { - String cnaFile= System.getProperty("user.home") + "/Downloads/curie-cna.xlsx"; + String cnaFile = homeDir + "/Downloads/curie-cna.xlsx"; - List<Map<String, String>> dataList = utilityService.serializeExcelDataNoIterator(cnaFile,0,1); + List<Map<String, String>> dataList = utilityService.serializeExcelDataNoIterator(cnaFile, 0, 1); for (Map<String, String> data : dataList) { String modelID = data.get("Model_ID"); - if (modelID.equals("LCF4")){ + if (modelID.equals("LCF4")) { - data.put("Sample_ID","LCF4p09/09/2009"); - data.put("sample_origin","engrafted tumor"); - data.put("Passage","4"); - data.put("Platform","CGH array"); + data.put("Sample_ID", "LCF4p09/09/2009"); + data.put("sample_origin", "engrafted tumor"); + data.put("Passage", "4"); + data.put("Platform", "CGH array"); } - if (modelID.equals("LCF9")){ + if (modelID.equals("LCF9")) { - data.put("Sample_ID","LCF9p16:19/05/2015"); - data.put("sample_origin","engrafted tumor"); - data.put("Passage","16"); - data.put("Platform","CGH array"); + data.put("Sample_ID", "LCF9p16:19/05/2015"); + data.put("sample_origin", "engrafted tumor"); + data.put("Passage", "16"); + data.put("Platform", "CGH array"); } - if (modelID.equals("LCF16")){ + if (modelID.equals("LCF16")) { - data.put("Sample_ID","LCF16p27:26/08/2016"); - data.put("sample_origin","engrafted tumor"); - data.put("Passage","27"); - data.put("Platform","CGH array"); + data.put("Sample_ID", "LCF16p27:26/08/2016"); + data.put("sample_origin", "engrafted tumor"); + data.put("Passage", "27"); + data.put("Platform", "CGH array"); } - if (modelID.equals("LCF26")){ + if (modelID.equals("LCF26")) { - data.put("Sample_ID","LCF26p3:23/09/2011"); - data.put("sample_origin","engrafted tumor"); - data.put("Passage","3"); - data.put("Platform","CGH array"); + data.put("Sample_ID", "LCF26p3:23/09/2011"); + data.put("sample_origin", "engrafted tumor"); + data.put("Passage", "3"); + data.put("Platform", "CGH array"); } } - String destination = homeDir+"/Downloads/curie-cna.csv"; + String destination = homeDir + "/Downloads/curie-cna.csv"; utilityService.writeCsvFile(dataList, destination); return dataList; } - - - - - - // FIX DERIVED DATA SHEET / PDX DETAILS IN CRL DATA @RequestMapping("/rewrite-crl") public Object crlTransform() { // UPDATE DERIVED DATA SHEET - String templateFile= System.getProperty("user.home") + "/Downloads/DATA/crl.xlsx"; - List<Map<String, String>> derivedDataSheet = utilityService.serializeExcelDataNoIterator(templateFile,6,4); + String templateFile = homeDir + "/Downloads/DATA/crl.xlsx"; + List<Map<String, String>> derivedDataSheet = utilityService.serializeExcelDataNoIterator(templateFile, 6, 4); List removedList = new ArrayList(); @@ -331,7 +254,7 @@ public class TransController { String modelID = data.get("Model ID"); // Replace Model Ids with prefix CRL- - data.put("Model ID","CRL-"+modelID); + data.put("Model ID", "CRL-" + modelID); // Deduct 1 from all passages String passage = data.get("Passage"); @@ -339,7 +262,7 @@ public class TransController { String cleanPassage = Integer.toString(Integer.parseInt(passage) - 1); data.put("Passage", cleanPassage); - }catch (Exception e){ + } catch (Exception e) { log.error("{}'s passage {} is not a meaningful passage data ", modelID, passage); @@ -348,10 +271,10 @@ public class TransController { } // Change Sample Origin to Xenograft - data.put("Sample origin","xenograft"); + data.put("Sample origin", "xenograft"); // remove Gene Expression Data - if ( data.get("Molecular Characterization type").contains("Gene expression") ){ + if (data.get("Molecular Characterization type").contains("Gene expression")) { removedList.add(data); } @@ -360,23 +283,23 @@ public class TransController { // Capture Map Keys to use as excel head List<String> xlsHead = new ArrayList<>(); - for (Map.Entry<String, String> entry : derivedDataSheet.get(0).entrySet() ) { + for (Map.Entry<String, String> entry : derivedDataSheet.get(0).entrySet()) { xlsHead.add(entry.getKey()); } - String destination = homeDir+"/Downloads/CRL-Derived_dataset_from_tumor.csv"; + String destination = homeDir + "/Downloads/CRL-Derived_dataset_from_tumor.csv"; utilityService.writeCsvFile(derivedDataSheet, destination); - utilityService.writeXLSXFile(derivedDataSheet,"CRL-Derived_dataset_from_tumor.xlsx", "Derived_dataset_from_tumor"); + utilityService.writeXLSXFile(derivedDataSheet, "CRL-Derived_dataset_from_tumor.xlsx", "Derived_dataset_from_tumor"); // UPDATE PDX DETAILS SHEET - List<Map<String, String>> pdxModelDetailSheet = utilityService.serializeExcelDataNoIterator(templateFile,4,4); + List<Map<String, String>> pdxModelDetailSheet = utilityService.serializeExcelDataNoIterator(templateFile, 4, 4); //pdxModelDetailSheet.remove(pdxModelDetailSheet.get(0)); // Group DerivedDataSheet By ModelID - Map<String, List<Map<String, String>> > groupedDerivedDataSheet = utilityService.groupDataByColumn(derivedDataSheet,"Model ID"); + Map<String, List<Map<String, String>>> groupedDerivedDataSheet = utilityService.groupDataByColumn(derivedDataSheet, "Model ID"); // Pull Model from ModelDetailSheet and look Up in DerivedDataSheet using the grouped version, pick the Passages and add to ModelDetailSheet @@ -392,66 +315,61 @@ public class TransController { Set<String> derivedDataPassages = new HashSet<>(); derivedDataPassages.add(modelDetailPassage); - try{ + try { - for (Map<String, String> derivedData : derivedDatas ){ + for (Map<String, String> derivedData : derivedDatas) { derivedDataPassages.add(derivedData.get("Passage")); } modelDetail.put("Passage", StringUtils.join(derivedDataPassages, ',')); - }catch (Exception e){ + } catch (Exception e) { - log.error(modelID+" Found in Model Detail, but not in derived data"); + log.error(modelID + " Found in Model Detail, but not in derived data"); } } - // Capture Map Keys to use as excel head xlsHead = new ArrayList<>(); - for (Map.Entry<String, String> entry : pdxModelDetailSheet.get(0).entrySet() ) { + for (Map.Entry<String, String> entry : pdxModelDetailSheet.get(0).entrySet()) { xlsHead.add(entry.getKey()); } - destination = homeDir+"/Downloads/CRL-PDX_Model_detail.csv"; + destination = homeDir + "/Downloads/CRL-PDX_Model_detail.csv"; utilityService.writeCsvFile(pdxModelDetailSheet, destination); - utilityService.writeXLSXFile(pdxModelDetailSheet,"CRL-PDX_Model_detail.xlsx", "PDX_Model_detail"); + utilityService.writeXLSXFile(pdxModelDetailSheet, "CRL-PDX_Model_detail.xlsx", "PDX_Model_detail"); return pdxModelDetailSheet; } - - - @RequestMapping("/move-crl-omic-file") public Object moveFile() { - - String templateFile= System.getProperty("user.home") + "/Downloads/template.xlsx"; - List<Map<String, String>> data = utilityService.serializeExcelDataNoIterator(templateFile,6,4); + String templateFile = homeDir + "/Downloads/template.xlsx"; + List<Map<String, String>> data = utilityService.serializeExcelDataNoIterator(templateFile, 6, 4); data.remove(data.get(0)); - for (Map<String, String> dData : data){ + for (Map<String, String> dData : data) { String sampleID = dData.get("sample ID"); String dataType = dData.get("Molecular Characterization type"); String sourceDir = (dataType.equals("Mutation")) ? "Mutation" : "Copy_Numbers"; - String destinationDir = sourceDir+"2"; + String destinationDir = sourceDir + "2"; String fileSuffix = (dataType.equals("Mutation")) ? "_mutation_list_pdxfinder.csv" : "_cna_list_pdxfinder.csv"; - String source = System.getProperty("user.home") + "/Downloads/TEMP/"+sourceDir+"/"+sampleID+fileSuffix; + String source = homeDir + "/Downloads/TEMP/" + sourceDir + "/" + sampleID + fileSuffix; - String destination = System.getProperty("user.home") + "/Downloads/TEMP/"+destinationDir+"/"+sampleID+fileSuffix; + String destination = homeDir + "/Downloads/TEMP/" + destinationDir + "/" + sampleID + fileSuffix; - utilityService.moveFile(source,destination); + utilityService.moveFile(source, destination); - log.info("Moving {} File ... ",dataType); + log.info("Moving {} File ... ", dataType); } @@ -459,24 +377,21 @@ public class TransController { } - - - @RequestMapping("/clean-crl-omic-files") public Object cleanCRLOMICFiles() { - List<String> csvHead = Arrays.asList("datasource","Model_ID","Sample_ID","sample_origin","Passage","host_strain_name","hgnc_symbol","amino_acid_change","nucleotide_change", - "consequence","read_depth","Allele_frequency","chromosome","seq_start_position","ref_allele","alt_allele","ucsc_gene_id", - "ncbi_gene_id","ensembl_gene_id","ensembl_transcript_id","rs_id_Variant","genome_assembly","Platform"); + List<String> csvHead = Arrays.asList("datasource", "Model_ID", "Sample_ID", "sample_origin", "Passage", "host_strain_name", "hgnc_symbol", "amino_acid_change", "nucleotide_change", + "consequence", "read_depth", "Allele_frequency", "chromosome", "seq_start_position", "ref_allele", "alt_allele", "ucsc_gene_id", + "ncbi_gene_id", "ensembl_gene_id", "ensembl_transcript_id", "rs_id_Variant", "genome_assembly", "Platform"); - String templateFile= homeDir + "/Downloads/template.xlsx"; - List<Map<String, String>> data = utilityService.serializeExcelDataNoIterator(templateFile,6,4); + String templateFile = homeDir + "/Downloads/template.xlsx"; + List<Map<String, String>> data = utilityService.serializeExcelDataNoIterator(templateFile, 6, 4); data.remove(data.get(0)); - for (Map<String, String> dData : data){ + for (Map<String, String> dData : data) { String sampleID = dData.get("sample ID"); String dataType = dData.get("Molecular Characterization type"); @@ -486,10 +401,10 @@ public class TransController { String fileSuffix = (dataType.equals("Mutation")) ? "_mutation_list_pdxfinder.csv" : "_cna_list_pdxfinder.csv"; - String destinationDir = sourceDir+"-Final"; + String destinationDir = sourceDir + "-Final"; - String source = homeDir+"/Downloads/TEMP/"+sourceDir+"/"+sampleID+fileSuffix; + String source = homeDir + "/Downloads/TEMP/" + sourceDir + "/" + sampleID + fileSuffix; log.info(source); @@ -499,11 +414,11 @@ public class TransController { String modelID = ""; for (Map<String, String> dataRow : dataList) { - modelID = "CRL-"+dataRow.get("Model_ID"); + modelID = "CRL-" + dataRow.get("Model_ID"); dataRow.put("Model_ID", modelID); } - String destination = homeDir+"/Downloads/TEMP/"+destinationDir+"/"+modelID+".csv"; + String destination = homeDir + "/Downloads/TEMP/" + destinationDir + "/" + modelID + ".csv"; utilityService.writeCsvFile(dataList, destination); @@ -515,11 +430,10 @@ public class TransController { } - @RequestMapping("/get-files") public Object getAllFiles() { - String source = homeDir+"/Downloads/TEMP/Mutation/"; + String source = homeDir + "/Downloads/TEMP/Mutation/"; utilityService.listAllFilesInADirectory(source); @@ -530,9 +444,9 @@ public class TransController { @RequestMapping("/get-files-size") public long whenGetReadableSize_thenCorrect() { - long directorySize = directorySize(homeDir+"/Downloads/TEMP/Mutation2-Final/"); + long directorySize = directorySize(homeDir + "/Downloads/TEMP/Mutation2-Final/"); - long oneFileSize = oneFileSize(homeDir+"/Downloads/TEMP/Mutation2-Final/CRL-97.csv"); + long oneFileSize = oneFileSize(homeDir + "/Downloads/TEMP/Mutation2-Final/CRL-97.csv"); // Time taken divided by file size times everything: @@ -543,7 +457,7 @@ public class TransController { public long oneFileSize(String fileLink) { - File file =new File(fileLink); + File file = new File(fileLink); long fileSize = file.length(); @@ -551,7 +465,7 @@ public class TransController { } - public long directorySize(String dirLink){ + public long directorySize(String dirLink) { long size = 0; @@ -563,7 +477,8 @@ public class TransController { .mapToLong(p -> p.toFile().length()) .sum(); - }catch (Exception e){ } + } catch (Exception e) { + } return size; } diff --git a/admin/src/main/resources/application.properties b/admin/src/main/resources/application.properties index c9a2b243b9aeee9a31a2cf76dd0f22d2d4076d4b..562756bc12b9a7b83832ac250d75b36495a1bbfb 100644 --- a/admin/src/main/resources/application.properties +++ b/admin/src/main/resources/application.properties @@ -17,7 +17,6 @@ spring.thymeleaf.cache=false server.port=8081 mappings.diagnosis.file = ""; - mappings.mappedTermUrl=http://localhost/data/mappings.json ## H2 Config @@ -26,7 +25,6 @@ spring.h2.console.path=/db-admin/console spring.h2.console.settings.web-allow-others=true # NON-GRAPH Datasource Config properties -#${HOME} spring.datasource.url=jdbc:h2:${data-dir}/h2-db/data;AUTO_SERVER=true;DB_CLOSE_ON_EXIT=FALSE spring.datasource.username=neo4j spring.datasource.password=neo5j @@ -35,8 +33,11 @@ spring.h2.console.settings.trace=true ## Hibernate Config spring.jpa.hibernate.ddl-auto=update +# Enable certain actuator endpoints +management.endpoint.env.enabled=true +management.endpoints.web.base-path=/manage +management.endpoints.web.exposure.include=env # root directory for local data feeds data-dir=/nfs/web-hx/mouseinformatics/pdx/finderroot -#${HOME}/PDXFinder diff --git a/admin/src/main/resources/static/css/animate.css b/admin/src/main/resources/static/css/animate.css deleted file mode 100644 index cf3eff8c48cbd0b7ee70212631a9faae0c119d7e..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/css/animate.css +++ /dev/null @@ -1,3340 +0,0 @@ -@charset "UTF-8"; - -/*! - * animate.css -http://daneden.me/animate - * Version - 3.5.1 - * Licensed under the MIT license - http://opensource.org/licenses/MIT - * - * Copyright (c) 2016 Daniel Eden - */ - -.animated { - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} - -.animated.infinite { - -webkit-animation-iteration-count: infinite; - animation-iteration-count: infinite; -} - -.animated.hinge { - -webkit-animation-duration: 2s; - animation-duration: 2s; -} - -.animated.flipOutX, -.animated.flipOutY, -.animated.bounceIn, -.animated.bounceOut { - -webkit-animation-duration: .75s; - animation-duration: .75s; -} - -@-webkit-keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -@keyframes bounce { - from, 20%, 53%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - -webkit-transform: translate3d(0,0,0); - transform: translate3d(0,0,0); - } - - 40%, 43% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -30px, 0); - transform: translate3d(0, -30px, 0); - } - - 70% { - -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); - -webkit-transform: translate3d(0, -15px, 0); - transform: translate3d(0, -15px, 0); - } - - 90% { - -webkit-transform: translate3d(0,-4px,0); - transform: translate3d(0,-4px,0); - } -} - -.bounce { - -webkit-animation-name: bounce; - animation-name: bounce; - -webkit-transform-origin: center bottom; - transform-origin: center bottom; -} - -@-webkit-keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -@keyframes flash { - from, 50%, to { - opacity: 1; - } - - 25%, 75% { - opacity: 0; - } -} - -.flash { - -webkit-animation-name: flash; - animation-name: flash; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes pulse { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 50% { - -webkit-transform: scale3d(1.05, 1.05, 1.05); - transform: scale3d(1.05, 1.05, 1.05); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.pulse { - -webkit-animation-name: pulse; - animation-name: pulse; -} - -@-webkit-keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes rubberBand { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 30% { - -webkit-transform: scale3d(1.25, 0.75, 1); - transform: scale3d(1.25, 0.75, 1); - } - - 40% { - -webkit-transform: scale3d(0.75, 1.25, 1); - transform: scale3d(0.75, 1.25, 1); - } - - 50% { - -webkit-transform: scale3d(1.15, 0.85, 1); - transform: scale3d(1.15, 0.85, 1); - } - - 65% { - -webkit-transform: scale3d(.95, 1.05, 1); - transform: scale3d(.95, 1.05, 1); - } - - 75% { - -webkit-transform: scale3d(1.05, .95, 1); - transform: scale3d(1.05, .95, 1); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.rubberBand { - -webkit-animation-name: rubberBand; - animation-name: rubberBand; -} - -@-webkit-keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -@keyframes shake { - from, to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - 10%, 30%, 50%, 70%, 90% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 20%, 40%, 60%, 80% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } -} - -.shake { - -webkit-animation-name: shake; - animation-name: shake; -} - -@-webkit-keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -@keyframes headShake { - 0% { - -webkit-transform: translateX(0); - transform: translateX(0); - } - - 6.5% { - -webkit-transform: translateX(-6px) rotateY(-9deg); - transform: translateX(-6px) rotateY(-9deg); - } - - 18.5% { - -webkit-transform: translateX(5px) rotateY(7deg); - transform: translateX(5px) rotateY(7deg); - } - - 31.5% { - -webkit-transform: translateX(-3px) rotateY(-5deg); - transform: translateX(-3px) rotateY(-5deg); - } - - 43.5% { - -webkit-transform: translateX(2px) rotateY(3deg); - transform: translateX(2px) rotateY(3deg); - } - - 50% { - -webkit-transform: translateX(0); - transform: translateX(0); - } -} - -.headShake { - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - -webkit-animation-name: headShake; - animation-name: headShake; -} - -@-webkit-keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -@keyframes swing { - 20% { - -webkit-transform: rotate3d(0, 0, 1, 15deg); - transform: rotate3d(0, 0, 1, 15deg); - } - - 40% { - -webkit-transform: rotate3d(0, 0, 1, -10deg); - transform: rotate3d(0, 0, 1, -10deg); - } - - 60% { - -webkit-transform: rotate3d(0, 0, 1, 5deg); - transform: rotate3d(0, 0, 1, 5deg); - } - - 80% { - -webkit-transform: rotate3d(0, 0, 1, -5deg); - transform: rotate3d(0, 0, 1, -5deg); - } - - to { - -webkit-transform: rotate3d(0, 0, 1, 0deg); - transform: rotate3d(0, 0, 1, 0deg); - } -} - -.swing { - -webkit-transform-origin: top center; - transform-origin: top center; - -webkit-animation-name: swing; - animation-name: swing; -} - -@-webkit-keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes tada { - from { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } - - 10%, 20% { - -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); - } - - 30%, 50%, 70%, 90% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); - } - - 40%, 60%, 80% { - -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); - } - - to { - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.tada { - -webkit-animation-name: tada; - animation-name: tada; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes wobble { - from { - -webkit-transform: none; - transform: none; - } - - 15% { - -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); - } - - 30% { - -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); - } - - 45% { - -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); - } - - 60% { - -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); - } - - 75% { - -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.wobble { - -webkit-animation-name: wobble; - animation-name: wobble; -} - -@-webkit-keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -@keyframes jello { - from, 11.1%, to { - -webkit-transform: none; - transform: none; - } - - 22.2% { - -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); - transform: skewX(-12.5deg) skewY(-12.5deg); - } - - 33.3% { - -webkit-transform: skewX(6.25deg) skewY(6.25deg); - transform: skewX(6.25deg) skewY(6.25deg); - } - - 44.4% { - -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); - transform: skewX(-3.125deg) skewY(-3.125deg); - } - - 55.5% { - -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); - transform: skewX(1.5625deg) skewY(1.5625deg); - } - - 66.6% { - -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); - transform: skewX(-0.78125deg) skewY(-0.78125deg); - } - - 77.7% { - -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); - transform: skewX(0.390625deg) skewY(0.390625deg); - } - - 88.8% { - -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - transform: skewX(-0.1953125deg) skewY(-0.1953125deg); - } -} - -.jello { - -webkit-animation-name: jello; - animation-name: jello; - -webkit-transform-origin: center; - transform-origin: center; -} - -@-webkit-keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -@keyframes bounceIn { - from, 20%, 40%, 60%, 80%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 20% { - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - 40% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(1.03, 1.03, 1.03); - transform: scale3d(1.03, 1.03, 1.03); - } - - 80% { - -webkit-transform: scale3d(.97, .97, .97); - transform: scale3d(.97, .97, .97); - } - - to { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.bounceIn { - -webkit-animation-name: bounceIn; - animation-name: bounceIn; -} - -@-webkit-keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInDown { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(0, -3000px, 0); - transform: translate3d(0, -3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, 25px, 0); - transform: translate3d(0, 25px, 0); - } - - 75% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, 5px, 0); - transform: translate3d(0, 5px, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInDown { - -webkit-animation-name: bounceInDown; - animation-name: bounceInDown; -} - -@-webkit-keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInLeft { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - 0% { - opacity: 0; - -webkit-transform: translate3d(-3000px, 0, 0); - transform: translate3d(-3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(25px, 0, 0); - transform: translate3d(25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(-10px, 0, 0); - transform: translate3d(-10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(5px, 0, 0); - transform: translate3d(5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInLeft { - -webkit-animation-name: bounceInLeft; - animation-name: bounceInLeft; -} - -@-webkit-keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -@keyframes bounceInRight { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(3000px, 0, 0); - transform: translate3d(3000px, 0, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(-25px, 0, 0); - transform: translate3d(-25px, 0, 0); - } - - 75% { - -webkit-transform: translate3d(10px, 0, 0); - transform: translate3d(10px, 0, 0); - } - - 90% { - -webkit-transform: translate3d(-5px, 0, 0); - transform: translate3d(-5px, 0, 0); - } - - to { - -webkit-transform: none; - transform: none; - } -} - -.bounceInRight { - -webkit-animation-name: bounceInRight; - animation-name: bounceInRight; -} - -@-webkit-keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes bounceInUp { - from, 60%, 75%, 90%, to { - -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); - } - - from { - opacity: 0; - -webkit-transform: translate3d(0, 3000px, 0); - transform: translate3d(0, 3000px, 0); - } - - 60% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - 75% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 90% { - -webkit-transform: translate3d(0, -5px, 0); - transform: translate3d(0, -5px, 0); - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.bounceInUp { - -webkit-animation-name: bounceInUp; - animation-name: bounceInUp; -} - -@-webkit-keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -@keyframes bounceOut { - 20% { - -webkit-transform: scale3d(.9, .9, .9); - transform: scale3d(.9, .9, .9); - } - - 50%, 55% { - opacity: 1; - -webkit-transform: scale3d(1.1, 1.1, 1.1); - transform: scale3d(1.1, 1.1, 1.1); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } -} - -.bounceOut { - -webkit-animation-name: bounceOut; - animation-name: bounceOut; -} - -@-webkit-keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes bounceOutDown { - 20% { - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, -20px, 0); - transform: translate3d(0, -20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.bounceOutDown { - -webkit-animation-name: bounceOutDown; - animation-name: bounceOutDown; -} - -@-webkit-keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes bounceOutLeft { - 20% { - opacity: 1; - -webkit-transform: translate3d(20px, 0, 0); - transform: translate3d(20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.bounceOutLeft { - -webkit-animation-name: bounceOutLeft; - animation-name: bounceOutLeft; -} - -@-webkit-keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes bounceOutRight { - 20% { - opacity: 1; - -webkit-transform: translate3d(-20px, 0, 0); - transform: translate3d(-20px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.bounceOutRight { - -webkit-animation-name: bounceOutRight; - animation-name: bounceOutRight; -} - -@-webkit-keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes bounceOutUp { - 20% { - -webkit-transform: translate3d(0, -10px, 0); - transform: translate3d(0, -10px, 0); - } - - 40%, 45% { - opacity: 1; - -webkit-transform: translate3d(0, 20px, 0); - transform: translate3d(0, 20px, 0); - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.bounceOutUp { - -webkit-animation-name: bounceOutUp; - animation-name: bounceOutUp; -} - -@-webkit-keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -@keyframes fadeIn { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -.fadeIn { - -webkit-animation-name: fadeIn; - animation-name: fadeIn; -} - -@-webkit-keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDown { - from { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDown { - -webkit-animation-name: fadeInDown; - animation-name: fadeInDown; -} - -@-webkit-keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInDownBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInDownBig { - -webkit-animation-name: fadeInDownBig; - animation-name: fadeInDownBig; -} - -@-webkit-keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeft { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeft { - -webkit-animation-name: fadeInLeft; - animation-name: fadeInLeft; -} - -@-webkit-keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInLeftBig { - from { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInLeftBig { - -webkit-animation-name: fadeInLeftBig; - animation-name: fadeInLeftBig; -} - -@-webkit-keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRight { - from { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRight { - -webkit-animation-name: fadeInRight; - animation-name: fadeInRight; -} - -@-webkit-keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInRightBig { - from { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInRightBig { - -webkit-animation-name: fadeInRightBig; - animation-name: fadeInRightBig; -} - -@-webkit-keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUp { - from { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUp { - -webkit-animation-name: fadeInUp; - animation-name: fadeInUp; -} - -@-webkit-keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes fadeInUpBig { - from { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.fadeInUpBig { - -webkit-animation-name: fadeInUpBig; - animation-name: fadeInUpBig; -} - -@-webkit-keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -@keyframes fadeOut { - from { - opacity: 1; - } - - to { - opacity: 0; - } -} - -.fadeOut { - -webkit-animation-name: fadeOut; - animation-name: fadeOut; -} - -@-webkit-keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes fadeOutDown { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.fadeOutDown { - -webkit-animation-name: fadeOutDown; - animation-name: fadeOutDown; -} - -@-webkit-keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -@keyframes fadeOutDownBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, 2000px, 0); - transform: translate3d(0, 2000px, 0); - } -} - -.fadeOutDownBig { - -webkit-animation-name: fadeOutDownBig; - animation-name: fadeOutDownBig; -} - -@-webkit-keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes fadeOutLeft { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.fadeOutLeft { - -webkit-animation-name: fadeOutLeft; - animation-name: fadeOutLeft; -} - -@-webkit-keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -@keyframes fadeOutLeftBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(-2000px, 0, 0); - transform: translate3d(-2000px, 0, 0); - } -} - -.fadeOutLeftBig { - -webkit-animation-name: fadeOutLeftBig; - animation-name: fadeOutLeftBig; -} - -@-webkit-keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes fadeOutRight { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.fadeOutRight { - -webkit-animation-name: fadeOutRight; - animation-name: fadeOutRight; -} - -@-webkit-keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -@keyframes fadeOutRightBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(2000px, 0, 0); - transform: translate3d(2000px, 0, 0); - } -} - -.fadeOutRightBig { - -webkit-animation-name: fadeOutRightBig; - animation-name: fadeOutRightBig; -} - -@-webkit-keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes fadeOutUp { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.fadeOutUp { - -webkit-animation-name: fadeOutUp; - animation-name: fadeOutUp; -} - -@-webkit-keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -@keyframes fadeOutUpBig { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(0, -2000px, 0); - transform: translate3d(0, -2000px, 0); - } -} - -.fadeOutUpBig { - -webkit-animation-name: fadeOutUpBig; - animation-name: fadeOutUpBig; -} - -@-webkit-keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -@keyframes flip { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - transform: perspective(400px) rotate3d(0, 1, 0, -360deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 40% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; - } - - 50% { - -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 80% { - -webkit-transform: perspective(400px) scale3d(.95, .95, .95); - transform: perspective(400px) scale3d(.95, .95, .95); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } -} - -.animated.flip { - -webkit-backface-visibility: visible; - backface-visibility: visible; - -webkit-animation-name: flip; - animation-name: flip; -} - -@-webkit-keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInX { - from { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - transform: perspective(400px) rotate3d(1, 0, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - transform: perspective(400px) rotate3d(1, 0, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInX { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInX; - animation-name: flipInX; -} - -@-webkit-keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -@keyframes flipInY { - from { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - opacity: 0; - } - - 40% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - transform: perspective(400px) rotate3d(0, 1, 0, -20deg); - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; - } - - 60% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - transform: perspective(400px) rotate3d(0, 1, 0, 10deg); - opacity: 1; - } - - 80% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - transform: perspective(400px) rotate3d(0, 1, 0, -5deg); - } - - to { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.flipInY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipInY; - animation-name: flipInY; -} - -@-webkit-keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutX { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - transform: perspective(400px) rotate3d(1, 0, 0, -20deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - transform: perspective(400px) rotate3d(1, 0, 0, 90deg); - opacity: 0; - } -} - -.flipOutX { - -webkit-animation-name: flipOutX; - animation-name: flipOutX; - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; -} - -@-webkit-keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -@keyframes flipOutY { - from { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } - - 30% { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - transform: perspective(400px) rotate3d(0, 1, 0, -15deg); - opacity: 1; - } - - to { - -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - transform: perspective(400px) rotate3d(0, 1, 0, 90deg); - opacity: 0; - } -} - -.flipOutY { - -webkit-backface-visibility: visible !important; - backface-visibility: visible !important; - -webkit-animation-name: flipOutY; - animation-name: flipOutY; -} - -@-webkit-keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes lightSpeedIn { - from { - -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); - transform: translate3d(100%, 0, 0) skewX(-30deg); - opacity: 0; - } - - 60% { - -webkit-transform: skewX(20deg); - transform: skewX(20deg); - opacity: 1; - } - - 80% { - -webkit-transform: skewX(-5deg); - transform: skewX(-5deg); - opacity: 1; - } - - to { - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.lightSpeedIn { - -webkit-animation-name: lightSpeedIn; - animation-name: lightSpeedIn; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; -} - -@-webkit-keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -@keyframes lightSpeedOut { - from { - opacity: 1; - } - - to { - -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); - transform: translate3d(100%, 0, 0) skewX(30deg); - opacity: 0; - } -} - -.lightSpeedOut { - -webkit-animation-name: lightSpeedOut; - animation-name: lightSpeedOut; - -webkit-animation-timing-function: ease-in; - animation-timing-function: ease-in; -} - -@-webkit-keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateIn { - from { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, -200deg); - transform: rotate3d(0, 0, 1, -200deg); - opacity: 0; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateIn { - -webkit-animation-name: rotateIn; - animation-name: rotateIn; -} - -@-webkit-keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownLeft { - -webkit-animation-name: rotateInDownLeft; - animation-name: rotateInDownLeft; -} - -@-webkit-keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInDownRight { - -webkit-animation-name: rotateInDownRight; - animation-name: rotateInDownRight; -} - -@-webkit-keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpLeft { - -webkit-animation-name: rotateInUpLeft; - animation-name: rotateInUpLeft; -} - -@-webkit-keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -@keyframes rotateInUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -90deg); - transform: rotate3d(0, 0, 1, -90deg); - opacity: 0; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: none; - transform: none; - opacity: 1; - } -} - -.rotateInUpRight { - -webkit-animation-name: rotateInUpRight; - animation-name: rotateInUpRight; -} - -@-webkit-keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -@keyframes rotateOut { - from { - -webkit-transform-origin: center; - transform-origin: center; - opacity: 1; - } - - to { - -webkit-transform-origin: center; - transform-origin: center; - -webkit-transform: rotate3d(0, 0, 1, 200deg); - transform: rotate3d(0, 0, 1, 200deg); - opacity: 0; - } -} - -.rotateOut { - -webkit-animation-name: rotateOut; - animation-name: rotateOut; -} - -@-webkit-keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, 45deg); - transform: rotate3d(0, 0, 1, 45deg); - opacity: 0; - } -} - -.rotateOutDownLeft { - -webkit-animation-name: rotateOutDownLeft; - animation-name: rotateOutDownLeft; -} - -@-webkit-keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutDownRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutDownRight { - -webkit-animation-name: rotateOutDownRight; - animation-name: rotateOutDownRight; -} - -@-webkit-keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -@keyframes rotateOutUpLeft { - from { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: left bottom; - transform-origin: left bottom; - -webkit-transform: rotate3d(0, 0, 1, -45deg); - transform: rotate3d(0, 0, 1, -45deg); - opacity: 0; - } -} - -.rotateOutUpLeft { - -webkit-animation-name: rotateOutUpLeft; - animation-name: rotateOutUpLeft; -} - -@-webkit-keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -@keyframes rotateOutUpRight { - from { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - opacity: 1; - } - - to { - -webkit-transform-origin: right bottom; - transform-origin: right bottom; - -webkit-transform: rotate3d(0, 0, 1, 90deg); - transform: rotate3d(0, 0, 1, 90deg); - opacity: 0; - } -} - -.rotateOutUpRight { - -webkit-animation-name: rotateOutUpRight; - animation-name: rotateOutUpRight; -} - -@-webkit-keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -@keyframes hinge { - 0% { - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 20%, 60% { - -webkit-transform: rotate3d(0, 0, 1, 80deg); - transform: rotate3d(0, 0, 1, 80deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - } - - 40%, 80% { - -webkit-transform: rotate3d(0, 0, 1, 60deg); - transform: rotate3d(0, 0, 1, 60deg); - -webkit-transform-origin: top left; - transform-origin: top left; - -webkit-animation-timing-function: ease-in-out; - animation-timing-function: ease-in-out; - opacity: 1; - } - - to { - -webkit-transform: translate3d(0, 700px, 0); - transform: translate3d(0, 700px, 0); - opacity: 0; - } -} - -.hinge { - -webkit-animation-name: hinge; - animation-name: hinge; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -@keyframes rollIn { - from { - opacity: 0; - -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); - } - - to { - opacity: 1; - -webkit-transform: none; - transform: none; - } -} - -.rollIn { - -webkit-animation-name: rollIn; - animation-name: rollIn; -} - -/* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ - -@-webkit-keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -@keyframes rollOut { - from { - opacity: 1; - } - - to { - opacity: 0; - -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); - } -} - -.rollOut { - -webkit-animation-name: rollOut; - animation-name: rollOut; -} - -@-webkit-keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -@keyframes zoomIn { - from { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - 50% { - opacity: 1; - } -} - -.zoomIn { - -webkit-animation-name: zoomIn; - animation-name: zoomIn; -} - -@-webkit-keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInDown { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInDown { - -webkit-animation-name: zoomInDown; - animation-name: zoomInDown; -} - -@-webkit-keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInLeft { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInLeft { - -webkit-animation-name: zoomInLeft; - animation-name: zoomInLeft; -} - -@-webkit-keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInRight { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInRight { - -webkit-animation-name: zoomInRight; - animation-name: zoomInRight; -} - -@-webkit-keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomInUp { - from { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - 60% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomInUp { - -webkit-animation-name: zoomInUp; - animation-name: zoomInUp; -} - -@-webkit-keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -@keyframes zoomOut { - from { - opacity: 1; - } - - 50% { - opacity: 0; - -webkit-transform: scale3d(.3, .3, .3); - transform: scale3d(.3, .3, .3); - } - - to { - opacity: 0; - } -} - -.zoomOut { - -webkit-animation-name: zoomOut; - animation-name: zoomOut; -} - -@-webkit-keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutDown { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutDown { - -webkit-animation-name: zoomOutDown; - animation-name: zoomOutDown; -} - -@-webkit-keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -@keyframes zoomOutLeft { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); - transform: scale(.1) translate3d(-2000px, 0, 0); - -webkit-transform-origin: left center; - transform-origin: left center; - } -} - -.zoomOutLeft { - -webkit-animation-name: zoomOutLeft; - animation-name: zoomOutLeft; -} - -@-webkit-keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -@keyframes zoomOutRight { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); - } - - to { - opacity: 0; - -webkit-transform: scale(.1) translate3d(2000px, 0, 0); - transform: scale(.1) translate3d(2000px, 0, 0); - -webkit-transform-origin: right center; - transform-origin: right center; - } -} - -.zoomOutRight { - -webkit-animation-name: zoomOutRight; - animation-name: zoomOutRight; -} - -@-webkit-keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -@keyframes zoomOutUp { - 40% { - opacity: 1; - -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); - -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); - } - - to { - opacity: 0; - -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); - -webkit-transform-origin: center bottom; - transform-origin: center bottom; - -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); - } -} - -.zoomOutUp { - -webkit-animation-name: zoomOutUp; - animation-name: zoomOutUp; -} - -@-webkit-keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInDown { - from { - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInDown { - -webkit-animation-name: slideInDown; - animation-name: slideInDown; -} - -@-webkit-keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInLeft { - from { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInLeft { - -webkit-animation-name: slideInLeft; - animation-name: slideInLeft; -} - -@-webkit-keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInRight { - from { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInRight { - -webkit-animation-name: slideInRight; - animation-name: slideInRight; -} - -@-webkit-keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@keyframes slideInUp { - from { - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - visibility: visible; - } - - to { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.slideInUp { - -webkit-animation-name: slideInUp; - animation-name: slideInUp; -} - -@-webkit-keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -@keyframes slideOutDown { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, 100%, 0); - transform: translate3d(0, 100%, 0); - } -} - -.slideOutDown { - -webkit-animation-name: slideOutDown; - animation-name: slideOutDown; -} - -@-webkit-keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -@keyframes slideOutLeft { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - } -} - -.slideOutLeft { - -webkit-animation-name: slideOutLeft; - animation-name: slideOutLeft; -} - -@-webkit-keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -@keyframes slideOutRight { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - } -} - -.slideOutRight { - -webkit-animation-name: slideOutRight; - animation-name: slideOutRight; -} - -@-webkit-keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -@keyframes slideOutUp { - from { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } - - to { - visibility: hidden; - -webkit-transform: translate3d(0, -100%, 0); - transform: translate3d(0, -100%, 0); - } -} - -.slideOutUp { - -webkit-animation-name: slideOutUp; - animation-name: slideOutUp; -} diff --git a/admin/src/main/resources/static/css/bootstrap.css b/admin/src/main/resources/static/css/bootstrap.css deleted file mode 100644 index bc4fe8fd8862bb31f37b0bedd0b05f5699d42084..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/css/bootstrap.css +++ /dev/null @@ -1,6757 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ -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; - } - .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.woff2') format('woff2'), 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: "\002a"; -} -.glyphicon-plus:before { - content: "\002b"; -} -.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"; -} -.glyphicon-cd:before { - content: "\e201"; -} -.glyphicon-save-file:before { - content: "\e202"; -} -.glyphicon-open-file:before { - content: "\e203"; -} -.glyphicon-level-up:before { - content: "\e204"; -} -.glyphicon-copy:before { - content: "\e205"; -} -.glyphicon-paste:before { - content: "\e206"; -} -.glyphicon-alert:before { - content: "\e209"; -} -.glyphicon-equalizer:before { - content: "\e210"; -} -.glyphicon-king:before { - content: "\e211"; -} -.glyphicon-queen:before { - content: "\e212"; -} -.glyphicon-pawn:before { - content: "\e213"; -} -.glyphicon-bishop:before { - content: "\e214"; -} -.glyphicon-knight:before { - content: "\e215"; -} -.glyphicon-baby-formula:before { - content: "\e216"; -} -.glyphicon-tent:before { - content: "\26fa"; -} -.glyphicon-blackboard:before { - content: "\e218"; -} -.glyphicon-bed:before { - content: "\e219"; -} -.glyphicon-apple:before { - content: "\f8ff"; -} -.glyphicon-erase:before { - content: "\e221"; -} -.glyphicon-hourglass:before { - content: "\231b"; -} -.glyphicon-lamp:before { - content: "\e223"; -} -.glyphicon-duplicate:before { - content: "\e224"; -} -.glyphicon-piggy-bank:before { - content: "\e225"; -} -.glyphicon-scissors:before { - content: "\e226"; -} -.glyphicon-bitcoin:before { - content: "\e227"; -} -.glyphicon-btc:before { - content: "\e227"; -} -.glyphicon-xbt:before { - content: "\e227"; -} -.glyphicon-yen:before { - content: "\00a5"; -} -.glyphicon-jpy:before { - content: "\00a5"; -} -.glyphicon-ruble:before { - content: "\20bd"; -} -.glyphicon-rub:before { - content: "\20bd"; -} -.glyphicon-scale:before { - content: "\e230"; -} -.glyphicon-ice-lolly:before { - content: "\e231"; -} -.glyphicon-ice-lolly-tasted:before { - content: "\e232"; -} -.glyphicon-education:before { - content: "\e233"; -} -.glyphicon-option-horizontal:before { - content: "\e234"; -} -.glyphicon-option-vertical:before { - content: "\e235"; -} -.glyphicon-menu-hamburger:before { - content: "\e236"; -} -.glyphicon-modal-window:before { - content: "\e237"; -} -.glyphicon-oil:before { - content: "\e238"; -} -.glyphicon-grain:before { - content: "\e239"; -} -.glyphicon-sunglasses:before { - content: "\e240"; -} -.glyphicon-text-size:before { - content: "\e241"; -} -.glyphicon-text-color:before { - content: "\e242"; -} -.glyphicon-text-background:before { - content: "\e243"; -} -.glyphicon-object-align-top:before { - content: "\e244"; -} -.glyphicon-object-align-bottom:before { - content: "\e245"; -} -.glyphicon-object-align-horizontal:before { - content: "\e246"; -} -.glyphicon-object-align-left:before { - content: "\e247"; -} -.glyphicon-object-align-vertical:before { - content: "\e248"; -} -.glyphicon-object-align-right:before { - content: "\e249"; -} -.glyphicon-triangle-right:before { - content: "\e250"; -} -.glyphicon-triangle-left:before { - content: "\e251"; -} -.glyphicon-triangle-bottom:before { - content: "\e252"; -} -.glyphicon-triangle-top:before { - content: "\e253"; -} -.glyphicon-console:before { - content: "\e254"; -} -.glyphicon-superscript:before { - content: "\e255"; -} -.glyphicon-subscript:before { - content: "\e256"; -} -.glyphicon-menu-left:before { - content: "\e257"; -} -.glyphicon-menu-right:before { - content: "\e258"; -} -.glyphicon-menu-down:before { - content: "\e259"; -} -.glyphicon-menu-up:before { - content: "\e260"; -} -* { - -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: 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; -} -[role="button"] { - cursor: pointer; -} -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, -a.text-primary:focus { - color: #286090; -} -.text-success { - color: #3c763d; -} -a.text-success:hover, -a.text-success:focus { - color: #2b542c; -} -.text-info { - color: #31708f; -} -a.text-info:hover, -a.text-info:focus { - color: #245269; -} -.text-warning { - color: #8a6d3b; -} -a.text-warning:hover, -a.text-warning:focus { - color: #66512c; -} -.text-danger { - color: #a94442; -} -a.text-danger:hover, -a.text-danger:focus { - color: #843534; -} -.bg-primary { - color: #fff; - background-color: #337ab7; -} -a.bg-primary:hover, -a.bg-primary:focus { - background-color: #286090; -} -.bg-success { - background-color: #dff0d8; -} -a.bg-success:hover, -a.bg-success:focus { - background-color: #c1e2b3; -} -.bg-info { - background-color: #d9edf7; -} -a.bg-info:hover, -a.bg-info:focus { - background-color: #afd9ee; -} -.bg-warning { - background-color: #fcf8e3; -} -a.bg-warning:hover, -a.bg-warning:focus { - background-color: #f7ecb5; -} -.bg-danger { - background-color: #f2dede; -} -a.bg-danger:hover, -a.bg-danger:focus { - 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-of-type(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: 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::-ms-expand { - background-color: transparent; - border: 0; -} -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - background-color: #eee; - opacity: 1; -} -.form-control[disabled], -fieldset[disabled] .form-control { - cursor: not-allowed; -} -textarea.form-control { - height: auto; -} -input[type="search"] { - -webkit-appearance: none; -} -@media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"].form-control, - input[type="time"].form-control, - input[type="datetime-local"].form-control, - input[type="month"].form-control { - line-height: 34px; - } - input[type="date"].input-sm, - input[type="time"].input-sm, - input[type="datetime-local"].input-sm, - input[type="month"].input-sm, - .input-group-sm input[type="date"], - .input-group-sm input[type="time"], - .input-group-sm input[type="datetime-local"], - .input-group-sm input[type="month"] { - line-height: 30px; - } - input[type="date"].input-lg, - input[type="time"].input-lg, - input[type="datetime-local"].input-lg, - input[type="month"].input-lg, - .input-group-lg input[type="date"], - .input-group-lg input[type="time"], - .input-group-lg input[type="datetime-local"], - .input-group-lg input[type="month"] { - 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 { - position: relative; - 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 { - min-height: 34px; - 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 { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -select.input-sm { - height: 30px; - line-height: 30px; -} -textarea.input-sm, -select[multiple].input-sm { - height: auto; -} -.form-group-sm .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.form-group-sm select.form-control { - height: 30px; - line-height: 30px; -} -.form-group-sm textarea.form-control, -.form-group-sm select[multiple].form-control { - height: auto; -} -.form-group-sm .form-control-static { - height: 30px; - min-height: 32px; - padding: 6px 10px; - font-size: 12px; - line-height: 1.5; -} -.input-lg { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px; -} -select.input-lg { - height: 46px; - line-height: 46px; -} -textarea.input-lg, -select[multiple].input-lg { - height: auto; -} -.form-group-lg .form-control { - height: 46px; - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px; -} -.form-group-lg select.form-control { - height: 46px; - line-height: 46px; -} -.form-group-lg textarea.form-control, -.form-group-lg select[multiple].form-control { - height: auto; -} -.form-group-lg .form-control-static { - height: 46px; - min-height: 38px; - padding: 11px 16px; - font-size: 18px; - line-height: 1.3333333; -} -.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, -.input-group-lg + .form-control-feedback, -.form-group-lg .form-control + .form-control-feedback { - width: 46px; - height: 46px; - line-height: 46px; -} -.input-sm + .form-control-feedback, -.input-group-sm + .form-control-feedback, -.form-group-sm .form-control + .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: 11px; - font-size: 18px; - } -} -@media (min-width: 768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 6px; - font-size: 12px; - } -} -.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: 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 { - cursor: not-allowed; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; - opacity: .65; -} -a.btn.disabled, -fieldset[disabled] a.btn { - pointer-events: none; -} -.btn-default { - color: #333; - background-color: #fff; - border-color: #ccc; -} -.btn-default:focus, -.btn-default.focus { - color: #333; - background-color: #e6e6e6; - border-color: #8c8c8c; -} -.btn-default:hover { - color: #333; - background-color: #e6e6e6; - border-color: #adadad; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - color: #333; - background-color: #e6e6e6; - border-color: #adadad; -} -.btn-default:active:hover, -.btn-default.active:hover, -.open > .dropdown-toggle.btn-default:hover, -.btn-default:active:focus, -.btn-default.active:focus, -.open > .dropdown-toggle.btn-default:focus, -.btn-default:active.focus, -.btn-default.active.focus, -.open > .dropdown-toggle.btn-default.focus { - color: #333; - background-color: #d4d4d4; - border-color: #8c8c8c; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - background-image: none; -} -.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 { - 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:focus, -.btn-primary.focus { - color: #fff; - background-color: #286090; - border-color: #122b40; -} -.btn-primary:hover { - color: #fff; - background-color: #286090; - border-color: #204d74; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - color: #fff; - background-color: #286090; - border-color: #204d74; -} -.btn-primary:active:hover, -.btn-primary.active:hover, -.open > .dropdown-toggle.btn-primary:hover, -.btn-primary:active:focus, -.btn-primary.active:focus, -.open > .dropdown-toggle.btn-primary:focus, -.btn-primary:active.focus, -.btn-primary.active.focus, -.open > .dropdown-toggle.btn-primary.focus { - color: #fff; - background-color: #204d74; - border-color: #122b40; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - background-image: none; -} -.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 { - 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:focus, -.btn-success.focus { - color: #fff; - background-color: #449d44; - border-color: #255625; -} -.btn-success:hover { - color: #fff; - background-color: #449d44; - border-color: #398439; -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - color: #fff; - background-color: #449d44; - border-color: #398439; -} -.btn-success:active:hover, -.btn-success.active:hover, -.open > .dropdown-toggle.btn-success:hover, -.btn-success:active:focus, -.btn-success.active:focus, -.open > .dropdown-toggle.btn-success:focus, -.btn-success:active.focus, -.btn-success.active.focus, -.open > .dropdown-toggle.btn-success.focus { - color: #fff; - background-color: #398439; - border-color: #255625; -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - background-image: none; -} -.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 { - 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:focus, -.btn-info.focus { - color: #fff; - background-color: #31b0d5; - border-color: #1b6d85; -} -.btn-info:hover { - color: #fff; - background-color: #31b0d5; - border-color: #269abc; -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - color: #fff; - background-color: #31b0d5; - border-color: #269abc; -} -.btn-info:active:hover, -.btn-info.active:hover, -.open > .dropdown-toggle.btn-info:hover, -.btn-info:active:focus, -.btn-info.active:focus, -.open > .dropdown-toggle.btn-info:focus, -.btn-info:active.focus, -.btn-info.active.focus, -.open > .dropdown-toggle.btn-info.focus { - color: #fff; - background-color: #269abc; - border-color: #1b6d85; -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - background-image: none; -} -.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 { - 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:focus, -.btn-warning.focus { - color: #fff; - background-color: #ec971f; - border-color: #985f0d; -} -.btn-warning:hover { - color: #fff; - background-color: #ec971f; - border-color: #d58512; -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - color: #fff; - background-color: #ec971f; - border-color: #d58512; -} -.btn-warning:active:hover, -.btn-warning.active:hover, -.open > .dropdown-toggle.btn-warning:hover, -.btn-warning:active:focus, -.btn-warning.active:focus, -.open > .dropdown-toggle.btn-warning:focus, -.btn-warning:active.focus, -.btn-warning.active.focus, -.open > .dropdown-toggle.btn-warning.focus { - color: #fff; - background-color: #d58512; - border-color: #985f0d; -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - background-image: none; -} -.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 { - 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:focus, -.btn-danger.focus { - color: #fff; - background-color: #c9302c; - border-color: #761c19; -} -.btn-danger:hover { - color: #fff; - background-color: #c9302c; - border-color: #ac2925; -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - color: #fff; - background-color: #c9302c; - border-color: #ac2925; -} -.btn-danger:active:hover, -.btn-danger.active:hover, -.open > .dropdown-toggle.btn-danger:hover, -.btn-danger:active:focus, -.btn-danger.active:focus, -.open > .dropdown-toggle.btn-danger:focus, -.btn-danger:active.focus, -.btn-danger.active.focus, -.open > .dropdown-toggle.btn-danger.focus { - color: #fff; - background-color: #ac2925; - border-color: #761c19; -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - background-image: none; -} -.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 { - 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.3333333; - 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; -} -.collapse.in { - display: block; -} -tr.collapse.in { - display: table-row; -} -tbody.collapse.in { - display: table-row-group; -} -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-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 dashed; - border-top: 4px solid \9; - border-right: 4px solid transparent; - border-left: 4px solid transparent; -} -.dropup, -.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: 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 dashed; - border-bottom: 4px solid \9; -} -.dropup .dropdown-menu, -.navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; -} -@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, -.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:not(:last-child) > .btn:last-child, -.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.btn-group > .btn-group:last-child:not(:first-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-left-radius: 4px; - 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-right-radius: 4px; - 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 .form-control:focus { - z-index: 3; -} -.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.3333333; - 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 { - z-index: 2; - 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; -} -.tab-content > .active { - display: block; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} -.navbar { - position: relative; - min-height: 50px; - margin-bottom: 20px; - border: 1px solid transparent; -} -@media (min-width: 768px) { - .navbar { - border-radius: 4px; - } -} -@media (min-width: 768px) { - .navbar-header { - float: left; - } -} -.navbar-collapse { - padding-right: 15px; - padding-left: 15px; - overflow-x: visible; - -webkit-overflow-scrolling: touch; - border-top: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); -} -.navbar-collapse.in { - overflow-y: auto; -} -@media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-fixed-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 { - margin-bottom: 0; - 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 { - z-index: 2; - 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: 3; - 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; - line-height: 1.3333333; -} -.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; - line-height: 1.5; -} -.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: middle; - background-color: #777; - border-radius: 10px; -} -.badge:empty { - display: none; -} -.btn .badge { - position: relative; - top: -1px; -} -.btn-xs .badge, -.btn-group-xs > .btn .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-top: 30px; - padding-bottom: 30px; - margin-bottom: 30px; - color: inherit; - background-color: #eee; -} -.jumbotron h1, -.jumbotron .h1 { - color: inherit; -} -.jumbotron p { - margin-bottom: 15px; - font-size: 21px; - font-weight: 200; -} -.jumbotron > hr { - border-top-color: #d5d5d5; -} -.container .jumbotron, -.container-fluid .jumbotron { - padding-right: 15px; - padding-left: 15px; - border-radius: 6px; -} -.jumbotron .container { - max-width: 100%; -} -@media screen and (min-width: 768px) { - .jumbotron { - padding-top: 48px; - padding-bottom: 48px; - } - .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, -.media-body { - overflow: hidden; - zoom: 1; -} -.media-body { - width: 10000px; -} -.media-object { - display: block; -} -.media-object.img-thumbnail { - max-width: none; -} -.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, -button.list-group-item { - color: #555; -} -a.list-group-item .list-group-item-heading, -button.list-group-item .list-group-item-heading { - color: #333; -} -a.list-group-item:hover, -button.list-group-item:hover, -a.list-group-item:focus, -button.list-group-item:focus { - color: #555; - text-decoration: none; - background-color: #f5f5f5; -} -button.list-group-item { - width: 100%; - text-align: left; -} -.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, -button.list-group-item-success { - color: #3c763d; -} -a.list-group-item-success .list-group-item-heading, -button.list-group-item-success .list-group-item-heading { - color: inherit; -} -a.list-group-item-success:hover, -button.list-group-item-success:hover, -a.list-group-item-success:focus, -button.list-group-item-success:focus { - color: #3c763d; - background-color: #d0e9c6; -} -a.list-group-item-success.active, -button.list-group-item-success.active, -a.list-group-item-success.active:hover, -button.list-group-item-success.active:hover, -a.list-group-item-success.active:focus, -button.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, -button.list-group-item-info { - color: #31708f; -} -a.list-group-item-info .list-group-item-heading, -button.list-group-item-info .list-group-item-heading { - color: inherit; -} -a.list-group-item-info:hover, -button.list-group-item-info:hover, -a.list-group-item-info:focus, -button.list-group-item-info:focus { - color: #31708f; - background-color: #c4e3f3; -} -a.list-group-item-info.active, -button.list-group-item-info.active, -a.list-group-item-info.active:hover, -button.list-group-item-info.active:hover, -a.list-group-item-info.active:focus, -button.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, -button.list-group-item-warning { - color: #8a6d3b; -} -a.list-group-item-warning .list-group-item-heading, -button.list-group-item-warning .list-group-item-heading { - color: inherit; -} -a.list-group-item-warning:hover, -button.list-group-item-warning:hover, -a.list-group-item-warning:focus, -button.list-group-item-warning:focus { - color: #8a6d3b; - background-color: #faf2cc; -} -a.list-group-item-warning.active, -button.list-group-item-warning.active, -a.list-group-item-warning.active:hover, -button.list-group-item-warning.active:hover, -a.list-group-item-warning.active:focus, -button.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, -button.list-group-item-danger { - color: #a94442; -} -a.list-group-item-danger .list-group-item-heading, -button.list-group-item-danger .list-group-item-heading { - color: inherit; -} -a.list-group-item-danger:hover, -button.list-group-item-danger:hover, -a.list-group-item-danger:focus, -button.list-group-item-danger:focus { - color: #a94442; - background-color: #ebcccc; -} -a.list-group-item-danger.active, -button.list-group-item-danger.active, -a.list-group-item-danger.active:hover, -button.list-group-item-danger.active:hover, -a.list-group-item-danger.active:focus, -button.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, -.panel-title > small, -.panel-title > .small, -.panel-title > small > a, -.panel-title > .small > 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 > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { - border-top-left-radius: 0; - border-top-right-radius: 0; -} -.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-16by9 { - padding-bottom: 56.25%; -} -.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: 1050; - display: none; - overflow: hidden; - -webkit-overflow-scrolling: touch; - outline: 0; -} -.modal.fade .modal-dialog { - -webkit-transition: -webkit-transform .3s ease-out; - -o-transition: -o-transform .3s ease-out; - transition: transform .3s ease-out; - -webkit-transform: 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: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000; -} -.modal-backdrop.fade { - filter: alpha(opacity=0); - opacity: 0; -} -.modal-backdrop.in { - filter: alpha(opacity=50); - opacity: .5; -} -.modal-header { - 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-style: normal; - font-weight: normal; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - white-space: normal; - filter: alpha(opacity=0); - opacity: 0; - - line-break: auto; -} -.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; - 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-style: normal; - font-weight: normal; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - 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); - - line-break: auto; -} -.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: 1000px; - perspective: 1000px; - } - .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); - background-color: rgba(0, 0, 0, 0); - 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; - margin-top: -10px; -} -.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; - font-family: serif; - line-height: 1; -} -.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: -10px; - font-size: 30px; - } - .carousel-control .glyphicon-chevron-left, - .carousel-control .icon-prev { - margin-left: -10px; - } - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next { - margin-right: -10px; - } - .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-header:before, -.modal-header: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-header: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; -} -.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 !important; - } - 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 !important; - } - 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 !important; - } - 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 !important; - } - 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 !important; - } - 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/admin/src/main/resources/static/css/font-awesome.css b/admin/src/main/resources/static/css/font-awesome.css deleted file mode 100644 index 38260c37baf7cd657dadb87d9c937abf94d56b94..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/css/font-awesome.css +++ /dev/null @@ -1,2337 +0,0 @@ -/*! - * Font Awesome 4.7.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.7.0'); - src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg'); - font-weight: normal; - font-style: normal; -} -.fa { - display: inline-block; - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -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; -} -.fa-pull-left { - float: left; -} -.fa-pull-right { - float: right; -} -.fa.fa-pull-left { - margin-right: .3em; -} -.fa.fa-pull-right { - margin-left: .3em; -} -/* Deprecated as of 4.4.0 */ -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.fa.pull-left { - margin-right: .3em; -} -.fa.pull-right { - margin-left: .3em; -} -.fa-spin { - -webkit-animation: fa-spin 2s infinite linear; - animation: fa-spin 2s infinite linear; -} -.fa-pulse { - -webkit-animation: fa-spin 1s infinite steps(8); - animation: fa-spin 1s infinite steps(8); -} -@-webkit-keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -.fa-rotate-90 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.fa-rotate-180 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.fa-rotate-270 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} -.fa-flip-horizontal { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} -.fa-flip-vertical { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; - -webkit-transform: scale(1, -1); - -ms-transform: scale(1, -1); - transform: scale(1, -1); -} -:root .fa-rotate-90, -:root .fa-rotate-180, -:root .fa-rotate-270, -:root .fa-flip-horizontal, -:root .fa-flip-vertical { - filter: none; -} -.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-remove:before, -.fa-close:before, -.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, -.fa-bar-chart: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-f:before, -.fa-facebook:before { - content: "\f09a"; -} -.fa-github:before { - content: "\f09b"; -} -.fa-unlock:before { - content: "\f09c"; -} -.fa-credit-card:before { - content: "\f09d"; -} -.fa-feed:before, -.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, -.fa-gratipay: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-pp: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-buoy: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-resistance: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-y-combinator-square:before, -.fa-yc-square:before, -.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"; -} -.fa-soccer-ball-o:before, -.fa-futbol-o:before { - content: "\f1e3"; -} -.fa-tty:before { - content: "\f1e4"; -} -.fa-binoculars:before { - content: "\f1e5"; -} -.fa-plug:before { - content: "\f1e6"; -} -.fa-slideshare:before { - content: "\f1e7"; -} -.fa-twitch:before { - content: "\f1e8"; -} -.fa-yelp:before { - content: "\f1e9"; -} -.fa-newspaper-o:before { - content: "\f1ea"; -} -.fa-wifi:before { - content: "\f1eb"; -} -.fa-calculator:before { - content: "\f1ec"; -} -.fa-paypal:before { - content: "\f1ed"; -} -.fa-google-wallet:before { - content: "\f1ee"; -} -.fa-cc-visa:before { - content: "\f1f0"; -} -.fa-cc-mastercard:before { - content: "\f1f1"; -} -.fa-cc-discover:before { - content: "\f1f2"; -} -.fa-cc-amex:before { - content: "\f1f3"; -} -.fa-cc-paypal:before { - content: "\f1f4"; -} -.fa-cc-stripe:before { - content: "\f1f5"; -} -.fa-bell-slash:before { - content: "\f1f6"; -} -.fa-bell-slash-o:before { - content: "\f1f7"; -} -.fa-trash:before { - content: "\f1f8"; -} -.fa-copyright:before { - content: "\f1f9"; -} -.fa-at:before { - content: "\f1fa"; -} -.fa-eyedropper:before { - content: "\f1fb"; -} -.fa-paint-brush:before { - content: "\f1fc"; -} -.fa-birthday-cake:before { - content: "\f1fd"; -} -.fa-area-chart:before { - content: "\f1fe"; -} -.fa-pie-chart:before { - content: "\f200"; -} -.fa-line-chart:before { - content: "\f201"; -} -.fa-lastfm:before { - content: "\f202"; -} -.fa-lastfm-square:before { - content: "\f203"; -} -.fa-toggle-off:before { - content: "\f204"; -} -.fa-toggle-on:before { - content: "\f205"; -} -.fa-bicycle:before { - content: "\f206"; -} -.fa-bus:before { - content: "\f207"; -} -.fa-ioxhost:before { - content: "\f208"; -} -.fa-angellist:before { - content: "\f209"; -} -.fa-cc:before { - content: "\f20a"; -} -.fa-shekel:before, -.fa-sheqel:before, -.fa-ils:before { - content: "\f20b"; -} -.fa-meanpath:before { - content: "\f20c"; -} -.fa-buysellads:before { - content: "\f20d"; -} -.fa-connectdevelop:before { - content: "\f20e"; -} -.fa-dashcube:before { - content: "\f210"; -} -.fa-forumbee:before { - content: "\f211"; -} -.fa-leanpub:before { - content: "\f212"; -} -.fa-sellsy:before { - content: "\f213"; -} -.fa-shirtsinbulk:before { - content: "\f214"; -} -.fa-simplybuilt:before { - content: "\f215"; -} -.fa-skyatlas:before { - content: "\f216"; -} -.fa-cart-plus:before { - content: "\f217"; -} -.fa-cart-arrow-down:before { - content: "\f218"; -} -.fa-diamond:before { - content: "\f219"; -} -.fa-ship:before { - content: "\f21a"; -} -.fa-user-secret:before { - content: "\f21b"; -} -.fa-motorcycle:before { - content: "\f21c"; -} -.fa-street-view:before { - content: "\f21d"; -} -.fa-heartbeat:before { - content: "\f21e"; -} -.fa-venus:before { - content: "\f221"; -} -.fa-mars:before { - content: "\f222"; -} -.fa-mercury:before { - content: "\f223"; -} -.fa-intersex:before, -.fa-transgender:before { - content: "\f224"; -} -.fa-transgender-alt:before { - content: "\f225"; -} -.fa-venus-double:before { - content: "\f226"; -} -.fa-mars-double:before { - content: "\f227"; -} -.fa-venus-mars:before { - content: "\f228"; -} -.fa-mars-stroke:before { - content: "\f229"; -} -.fa-mars-stroke-v:before { - content: "\f22a"; -} -.fa-mars-stroke-h:before { - content: "\f22b"; -} -.fa-neuter:before { - content: "\f22c"; -} -.fa-genderless:before { - content: "\f22d"; -} -.fa-facebook-official:before { - content: "\f230"; -} -.fa-pinterest-p:before { - content: "\f231"; -} -.fa-whatsapp:before { - content: "\f232"; -} -.fa-server:before { - content: "\f233"; -} -.fa-user-plus:before { - content: "\f234"; -} -.fa-user-times:before { - content: "\f235"; -} -.fa-hotel:before, -.fa-bed:before { - content: "\f236"; -} -.fa-viacoin:before { - content: "\f237"; -} -.fa-train:before { - content: "\f238"; -} -.fa-subway:before { - content: "\f239"; -} -.fa-medium:before { - content: "\f23a"; -} -.fa-yc:before, -.fa-y-combinator:before { - content: "\f23b"; -} -.fa-optin-monster:before { - content: "\f23c"; -} -.fa-opencart:before { - content: "\f23d"; -} -.fa-expeditedssl:before { - content: "\f23e"; -} -.fa-battery-4:before, -.fa-battery:before, -.fa-battery-full:before { - content: "\f240"; -} -.fa-battery-3:before, -.fa-battery-three-quarters:before { - content: "\f241"; -} -.fa-battery-2:before, -.fa-battery-half:before { - content: "\f242"; -} -.fa-battery-1:before, -.fa-battery-quarter:before { - content: "\f243"; -} -.fa-battery-0:before, -.fa-battery-empty:before { - content: "\f244"; -} -.fa-mouse-pointer:before { - content: "\f245"; -} -.fa-i-cursor:before { - content: "\f246"; -} -.fa-object-group:before { - content: "\f247"; -} -.fa-object-ungroup:before { - content: "\f248"; -} -.fa-sticky-note:before { - content: "\f249"; -} -.fa-sticky-note-o:before { - content: "\f24a"; -} -.fa-cc-jcb:before { - content: "\f24b"; -} -.fa-cc-diners-club:before { - content: "\f24c"; -} -.fa-clone:before { - content: "\f24d"; -} -.fa-balance-scale:before { - content: "\f24e"; -} -.fa-hourglass-o:before { - content: "\f250"; -} -.fa-hourglass-1:before, -.fa-hourglass-start:before { - content: "\f251"; -} -.fa-hourglass-2:before, -.fa-hourglass-half:before { - content: "\f252"; -} -.fa-hourglass-3:before, -.fa-hourglass-end:before { - content: "\f253"; -} -.fa-hourglass:before { - content: "\f254"; -} -.fa-hand-grab-o:before, -.fa-hand-rock-o:before { - content: "\f255"; -} -.fa-hand-stop-o:before, -.fa-hand-paper-o:before { - content: "\f256"; -} -.fa-hand-scissors-o:before { - content: "\f257"; -} -.fa-hand-lizard-o:before { - content: "\f258"; -} -.fa-hand-spock-o:before { - content: "\f259"; -} -.fa-hand-pointer-o:before { - content: "\f25a"; -} -.fa-hand-peace-o:before { - content: "\f25b"; -} -.fa-trademark:before { - content: "\f25c"; -} -.fa-registered:before { - content: "\f25d"; -} -.fa-creative-commons:before { - content: "\f25e"; -} -.fa-gg:before { - content: "\f260"; -} -.fa-gg-circle:before { - content: "\f261"; -} -.fa-tripadvisor:before { - content: "\f262"; -} -.fa-odnoklassniki:before { - content: "\f263"; -} -.fa-odnoklassniki-square:before { - content: "\f264"; -} -.fa-get-pocket:before { - content: "\f265"; -} -.fa-wikipedia-w:before { - content: "\f266"; -} -.fa-safari:before { - content: "\f267"; -} -.fa-chrome:before { - content: "\f268"; -} -.fa-firefox:before { - content: "\f269"; -} -.fa-opera:before { - content: "\f26a"; -} -.fa-internet-explorer:before { - content: "\f26b"; -} -.fa-tv:before, -.fa-television:before { - content: "\f26c"; -} -.fa-contao:before { - content: "\f26d"; -} -.fa-500px:before { - content: "\f26e"; -} -.fa-amazon:before { - content: "\f270"; -} -.fa-calendar-plus-o:before { - content: "\f271"; -} -.fa-calendar-minus-o:before { - content: "\f272"; -} -.fa-calendar-times-o:before { - content: "\f273"; -} -.fa-calendar-check-o:before { - content: "\f274"; -} -.fa-industry:before { - content: "\f275"; -} -.fa-map-pin:before { - content: "\f276"; -} -.fa-map-signs:before { - content: "\f277"; -} -.fa-map-o:before { - content: "\f278"; -} -.fa-map:before { - content: "\f279"; -} -.fa-commenting:before { - content: "\f27a"; -} -.fa-commenting-o:before { - content: "\f27b"; -} -.fa-houzz:before { - content: "\f27c"; -} -.fa-vimeo:before { - content: "\f27d"; -} -.fa-black-tie:before { - content: "\f27e"; -} -.fa-fonticons:before { - content: "\f280"; -} -.fa-reddit-alien:before { - content: "\f281"; -} -.fa-edge:before { - content: "\f282"; -} -.fa-credit-card-alt:before { - content: "\f283"; -} -.fa-codiepie:before { - content: "\f284"; -} -.fa-modx:before { - content: "\f285"; -} -.fa-fort-awesome:before { - content: "\f286"; -} -.fa-usb:before { - content: "\f287"; -} -.fa-product-hunt:before { - content: "\f288"; -} -.fa-mixcloud:before { - content: "\f289"; -} -.fa-scribd:before { - content: "\f28a"; -} -.fa-pause-circle:before { - content: "\f28b"; -} -.fa-pause-circle-o:before { - content: "\f28c"; -} -.fa-stop-circle:before { - content: "\f28d"; -} -.fa-stop-circle-o:before { - content: "\f28e"; -} -.fa-shopping-bag:before { - content: "\f290"; -} -.fa-shopping-basket:before { - content: "\f291"; -} -.fa-hashtag:before { - content: "\f292"; -} -.fa-bluetooth:before { - content: "\f293"; -} -.fa-bluetooth-b:before { - content: "\f294"; -} -.fa-percent:before { - content: "\f295"; -} -.fa-gitlab:before { - content: "\f296"; -} -.fa-wpbeginner:before { - content: "\f297"; -} -.fa-wpforms:before { - content: "\f298"; -} -.fa-envira:before { - content: "\f299"; -} -.fa-universal-access:before { - content: "\f29a"; -} -.fa-wheelchair-alt:before { - content: "\f29b"; -} -.fa-question-circle-o:before { - content: "\f29c"; -} -.fa-blind:before { - content: "\f29d"; -} -.fa-audio-description:before { - content: "\f29e"; -} -.fa-volume-control-phone:before { - content: "\f2a0"; -} -.fa-braille:before { - content: "\f2a1"; -} -.fa-assistive-listening-systems:before { - content: "\f2a2"; -} -.fa-asl-interpreting:before, -.fa-american-sign-language-interpreting:before { - content: "\f2a3"; -} -.fa-deafness:before, -.fa-hard-of-hearing:before, -.fa-deaf:before { - content: "\f2a4"; -} -.fa-glide:before { - content: "\f2a5"; -} -.fa-glide-g:before { - content: "\f2a6"; -} -.fa-signing:before, -.fa-sign-language:before { - content: "\f2a7"; -} -.fa-low-vision:before { - content: "\f2a8"; -} -.fa-viadeo:before { - content: "\f2a9"; -} -.fa-viadeo-square:before { - content: "\f2aa"; -} -.fa-snapchat:before { - content: "\f2ab"; -} -.fa-snapchat-ghost:before { - content: "\f2ac"; -} -.fa-snapchat-square:before { - content: "\f2ad"; -} -.fa-pied-piper:before { - content: "\f2ae"; -} -.fa-first-order:before { - content: "\f2b0"; -} -.fa-yoast:before { - content: "\f2b1"; -} -.fa-themeisle:before { - content: "\f2b2"; -} -.fa-google-plus-circle:before, -.fa-google-plus-official:before { - content: "\f2b3"; -} -.fa-fa:before, -.fa-font-awesome:before { - content: "\f2b4"; -} -.fa-handshake-o:before { - content: "\f2b5"; -} -.fa-envelope-open:before { - content: "\f2b6"; -} -.fa-envelope-open-o:before { - content: "\f2b7"; -} -.fa-linode:before { - content: "\f2b8"; -} -.fa-address-book:before { - content: "\f2b9"; -} -.fa-address-book-o:before { - content: "\f2ba"; -} -.fa-vcard:before, -.fa-address-card:before { - content: "\f2bb"; -} -.fa-vcard-o:before, -.fa-address-card-o:before { - content: "\f2bc"; -} -.fa-user-circle:before { - content: "\f2bd"; -} -.fa-user-circle-o:before { - content: "\f2be"; -} -.fa-user-o:before { - content: "\f2c0"; -} -.fa-id-badge:before { - content: "\f2c1"; -} -.fa-drivers-license:before, -.fa-id-card:before { - content: "\f2c2"; -} -.fa-drivers-license-o:before, -.fa-id-card-o:before { - content: "\f2c3"; -} -.fa-quora:before { - content: "\f2c4"; -} -.fa-free-code-camp:before { - content: "\f2c5"; -} -.fa-telegram:before { - content: "\f2c6"; -} -.fa-thermometer-4:before, -.fa-thermometer:before, -.fa-thermometer-full:before { - content: "\f2c7"; -} -.fa-thermometer-3:before, -.fa-thermometer-three-quarters:before { - content: "\f2c8"; -} -.fa-thermometer-2:before, -.fa-thermometer-half:before { - content: "\f2c9"; -} -.fa-thermometer-1:before, -.fa-thermometer-quarter:before { - content: "\f2ca"; -} -.fa-thermometer-0:before, -.fa-thermometer-empty:before { - content: "\f2cb"; -} -.fa-shower:before { - content: "\f2cc"; -} -.fa-bathtub:before, -.fa-s15:before, -.fa-bath:before { - content: "\f2cd"; -} -.fa-podcast:before { - content: "\f2ce"; -} -.fa-window-maximize:before { - content: "\f2d0"; -} -.fa-window-minimize:before { - content: "\f2d1"; -} -.fa-window-restore:before { - content: "\f2d2"; -} -.fa-times-rectangle:before, -.fa-window-close:before { - content: "\f2d3"; -} -.fa-times-rectangle-o:before, -.fa-window-close-o:before { - content: "\f2d4"; -} -.fa-bandcamp:before { - content: "\f2d5"; -} -.fa-grav:before { - content: "\f2d6"; -} -.fa-etsy:before { - content: "\f2d7"; -} -.fa-imdb:before { - content: "\f2d8"; -} -.fa-ravelry:before { - content: "\f2d9"; -} -.fa-eercast:before { - content: "\f2da"; -} -.fa-microchip:before { - content: "\f2db"; -} -.fa-snowflake-o:before { - content: "\f2dc"; -} -.fa-superpowers:before { - content: "\f2dd"; -} -.fa-wpexplorer:before { - content: "\f2de"; -} -.fa-meetup:before { - content: "\f2e0"; -} -.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; -} diff --git a/admin/src/main/resources/static/css/style.css b/admin/src/main/resources/static/css/style.css deleted file mode 100755 index 5508ad65f89b2178bc03c2a87d5f767a8c211fbe..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/css/style.css +++ /dev/null @@ -1,6975 +0,0 @@ -@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700"); -@import url("https://fonts.googleapis.com/css?family=Roboto:400,300,500,700"); - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight: 100; -} -h1 { - font-size: 30px; -} -h2 { - font-size: 24px; -} -h3 { - font-size: 16px; -} -h4 { - font-size: 14px; -} -h5 { - font-size: 12px; -} -h6 { - font-size: 10px; -} -h3, -h4, -h5 { - margin-top: 5px; - font-weight: 600; -} -.nav > li > a { - color: #a7b1c2; - font-weight: 600; - padding: 14px 20px 14px 25px; -} -.nav.navbar-right > li > a { - color: #999c9e; -} -.nav > li.active > a { - color: #ffffff; -} -.navbar-default .nav > li > a:hover, -.navbar-default .nav > li > a:focus { - background-color: #293846; - color: white; -} -.nav .open > a, -.nav .open > a:hover, -.nav .open > a:focus { - background: #fff; -} -.nav.navbar-top-links > li > a:hover, -.nav.navbar-top-links > li > a:focus { - background-color: transparent; -} -.nav > li > a i { - margin-right: 6px; -} -.navbar { - border: 0; -} -.navbar-default { - background-color: transparent; - border-color: #2f4050; -} -.navbar-top-links li { - display: inline-block; -} -.navbar-top-links li:last-child { - margin-right: 40px; -} -.body-small .navbar-top-links li:last-child { - margin-right: 0; -} -.navbar-top-links li a { - padding: 20px 10px; - min-height: 50px; -} -.dropdown-menu { - border: medium none; - border-radius: 3px; - box-shadow: 0 0 3px rgba(86, 96, 117, 0.7); - display: none; - float: left; - font-size: 12px; - left: 0; - list-style: none outside none; - padding: 0; - position: absolute; - text-shadow: none; - top: 100%; - z-index: 1000; -} -.dropdown-menu > li > a { - border-radius: 3px; - color: inherit; - line-height: 25px; - margin: 4px; - text-align: left; - font-weight: normal; -} -.dropdown-menu > li > a.font-bold { - font-weight: 600; -} -.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; -} -.dropdown-messages, -.dropdown-alerts { - padding: 10px 10px 10px 10px; -} -.dropdown-messages li a, -.dropdown-alerts li a { - font-size: 12px; -} -.dropdown-messages li em, -.dropdown-alerts li em { - font-size: 10px; -} -.nav.navbar-top-links .dropdown-alerts a { - font-size: 12px; -} - -.pace-done .nav-header { - transition: all 0.4s; -} -.nav > li.active { - border-left: 4px solid #19aa8d; - background: #293846; -} -.nav.nav-second-level > li.active { - border: none; -} -.nav.nav-second-level.collapse[style] { - height: auto !important; -} -.nav-header a { - color: #DFE4ED; -} -.nav-header .text-muted { - color: #8095a8; -} -.minimalize-styl-2 { - padding: 4px 12px; - margin: 14px 5px 5px 20px; - font-size: 14px; - float: left; -} -.navbar-form-custom { - float: left; - height: 50px; - padding: 0; - width: 200px; - display: inline-table; -} -.navbar-form-custom .form-group { - margin-bottom: 0; -} -.nav.navbar-top-links a { - font-size: 14px; -} -.navbar-form-custom .form-control { - background: none repeat scroll 0 0 rgba(0, 0, 0, 0); - border: medium none; - font-size: 14px; - height: 60px; - margin: 0; - z-index: 2000; -} -.count-info .label { - line-height: 12px; - padding: 2px 5px; - position: absolute; - right: 6px; - top: 12px; -} -.arrow { - float: right; -} -.fa.arrow:before { - content: "\f104"; -} -.active > a > .fa.arrow:before { - content: "\f107"; -} -.nav-second-level li, -.nav-third-level li { - border-bottom: none !important; -} -.nav-second-level li a { - padding: 7px 10px 7px 10px; - padding-left: 52px; -} -.nav-third-level li a { - padding-left: 62px; -} -.nav-second-level li:last-child { - margin-bottom: 10px; -} -body:not(.fixed-sidebar):not(.canvas-menu).mini-navbar .nav li:hover > .nav-second-level, -.mini-navbar .nav li:focus > .nav-second-level { - display: block; - border-radius: 0 2px 2px 0; - min-width: 140px; - height: auto; -} -body.mini-navbar .navbar-default .nav > li > .nav-second-level li a { - font-size: 12px; - border-radius: 3px; -} -.fixed-nav .slimScrollDiv #side-menu { - padding-bottom: 60px; -} -.mini-navbar .nav-second-level li a { - padding: 10px 10px 10px 15px; -} -.mini-navbar .nav-second-level { - position: absolute; - left: 70px; - top: 0; - background-color: #2f4050; - padding: 10px 10px 10px 10px; - font-size: 12px; -} -.canvas-menu.mini-navbar .nav-second-level { - background: #293846; -} -.mini-navbar li.active .nav-second-level { - left: 65px; -} -.navbar-default .special_link a { - background: #007C82; - color: white; -} -.navbar-default .special_link a:hover { - background: #17987e !important; - color: white; -} -.navbar-default .special_link a span.label { - background: #fff; - color: #007C82; -} -.navbar-default .landing_link a { - background: #1cc09f; - color: white; -} -.navbar-default .landing_link a:hover { - background: #007C82 !important; - color: white; -} -.navbar-default .landing_link a span.label { - background: #fff; - color: #1cc09f; -} -.logo-element { - text-align: center; - font-size: 18px; - font-weight: 600; - color: white; - display: none; - padding: 18px 0; -} -.pace-done .navbar-static-side, -.pace-done .nav-header, -.pace-done li.active, -.pace-done #page-wrapper, -.pace-done .footer { - -webkit-transition: all 0.4s; - -moz-transition: all 0.4s; - -o-transition: all 0.4s; - transition: all 0.4s; -} -.navbar-fixed-top { - background: #fff; - transition-duration: 0.4s; - border-bottom: 1px solid #e7eaec !important; - z-index: 2030; -} -.navbar-fixed-top, -.navbar-static-top { - background: #f3f3f4; -} -.fixed-nav #wrapper { - margin-top: 0; -} -body.fixed-nav #wrapper .navbar-static-side, -body.fixed-nav #wrapper #page-wrapper { - margin-top: 60px; -} -body.top-navigation.fixed-nav #wrapper #page-wrapper { - margin-top: 0; -} -body.fixed-nav.fixed-nav-basic .navbar-fixed-top { - left: 220px; -} -body.fixed-nav.fixed-nav-basic.mini-navbar .navbar-fixed-top { - left: 70px; -} -body.fixed-nav.fixed-nav-basic.fixed-sidebar.mini-navbar .navbar-fixed-top { - left: 0; -} -body.fixed-nav.fixed-nav-basic #wrapper .navbar-static-side { - margin-top: 0; -} -body.fixed-nav.fixed-nav-basic.body-small .navbar-fixed-top { - left: 0; -} -body.fixed-nav.fixed-nav-basic.fixed-sidebar.mini-navbar.body-small .navbar-fixed-top { - left: 220px; -} -.fixed-nav .minimalize-styl-2 { - margin: 14px 5px 5px 15px; -} -.body-small .navbar-fixed-top { - margin-left: 0; -} -body.mini-navbar .navbar-static-side { - width: 70px; -} -body.mini-navbar .profile-element, -body.mini-navbar .nav-label, -body.mini-navbar .navbar-default .nav li a span { - display: none; -} -body.canvas-menu .profile-element { - display: block; -} -body:not(.fixed-sidebar):not(.canvas-menu).mini-navbar .nav-second-level { - display: none; -} -body.mini-navbar .navbar-default .nav > li > a { - font-size: 16px; -} -body.mini-navbar .logo-element { - display: block; -} -body.canvas-menu .logo-element { - display: none; -} -body.mini-navbar .nav-header { - padding: 0; - background-color: #007C82; -} -body.canvas-menu .nav-header { - padding: 33px 25px; -} -body.mini-navbar #page-wrapper { - margin: 0 0 0 70px; -} -body.fixed-sidebar.mini-navbar .footer, -body.canvas-menu.mini-navbar .footer { - margin: 0 0 0 0 !important; -} -body.canvas-menu.mini-navbar #page-wrapper, -body.canvas-menu.mini-navbar .footer { - margin: 0 0 0 0; -} -body.fixed-sidebar .navbar-static-side, -body.canvas-menu .navbar-static-side { - position: fixed; - width: 220px; - z-index: 2001; - height: 100%; -} -body.fixed-sidebar.mini-navbar .navbar-static-side { - width: 0; -} -body.fixed-sidebar.mini-navbar #page-wrapper { - margin: 0 0 0 0; -} -body.body-small.fixed-sidebar.mini-navbar #page-wrapper { - margin: 0 0 0 220px; -} -body.body-small.fixed-sidebar.mini-navbar .navbar-static-side { - width: 220px; -} -.fixed-sidebar.mini-navbar .nav li:focus > .nav-second-level, -.canvas-menu.mini-navbar .nav li:focus > .nav-second-level { - display: block; - height: auto; -} -body.fixed-sidebar.mini-navbar .navbar-default .nav > li > .nav-second-level li a { - font-size: 12px; - border-radius: 3px; -} -body.canvas-menu.mini-navbar .navbar-default .nav > li > .nav-second-level li a { - font-size: 13px; - border-radius: 3px; -} -.fixed-sidebar.mini-navbar .nav-second-level li a, -.canvas-menu.mini-navbar .nav-second-level li a { - padding: 10px 10px 10px 15px; -} -.fixed-sidebar.mini-navbar .nav-second-level, -.canvas-menu.mini-navbar .nav-second-level { - position: relative; - padding: 0; - font-size: 13px; -} -.fixed-sidebar.mini-navbar li.active .nav-second-level, -.canvas-menu.mini-navbar li.active .nav-second-level { - left: 0; -} -body.fixed-sidebar.mini-navbar .navbar-default .nav > li > a, -body.canvas-menu.mini-navbar .navbar-default .nav > li > a { - font-size: 13px; -} -body.fixed-sidebar.mini-navbar .nav-label, -body.fixed-sidebar.mini-navbar .navbar-default .nav li a span, -body.canvas-menu.mini-navbar .nav-label, -body.canvas-menu.mini-navbar .navbar-default .nav li a span { - display: inline; -} -body.canvas-menu.mini-navbar .navbar-default .nav li .profile-element a span { - display: block; -} -.canvas-menu.mini-navbar .nav-second-level li a, -.fixed-sidebar.mini-navbar .nav-second-level li a { - padding: 7px 10px 7px 52px; -} -.fixed-sidebar.mini-navbar .nav-second-level, -.canvas-menu.mini-navbar .nav-second-level { - left: 0; -} -body.canvas-menu nav.navbar-static-side { - z-index: 2001; - background: #2f4050; - height: 100%; - position: fixed; - display: none; -} -body.canvas-menu.mini-navbar nav.navbar-static-side { - display: block; - width: 220px; -} -.top-navigation #page-wrapper { - margin-left: 0; -} -.top-navigation .navbar-nav .dropdown-menu > .active > a { - background: white; - color: #007C82; - font-weight: bold; -} -.white-bg .navbar-fixed-top, -.white-bg .navbar-static-top { - background: #fff; -} -.top-navigation .navbar { - margin-bottom: 0; -} -.top-navigation .nav > li > a { - padding: 15px 20px; - color: #676a6c; -} -.top-navigation .nav > li a:hover, -.top-navigation .nav > li a:focus { - background: #fff; - color: #007C82; -} -.top-navigation .nav > li.active { - background: #fff; - border: none; -} -.top-navigation .nav > li.active > a { - color: #007C82; -} -.top-navigation .navbar-right { - margin-right: 10px; -} -.top-navigation .navbar-nav .dropdown-menu { - box-shadow: none; - border: 1px solid #e7eaec; -} -.top-navigation .dropdown-menu > li > a { - margin: 0; - padding: 7px 20px; -} -.navbar .dropdown-menu { - margin-top: 0; -} -.top-navigation .navbar-brand { - background: #007C82; - color: #fff; - padding: 15px 25px; -} -.top-navigation .navbar-top-links li:last-child { - margin-right: 0; -} -.top-navigation.mini-navbar #page-wrapper, -.top-navigation.body-small.fixed-sidebar.mini-navbar #page-wrapper, -.mini-navbar .top-navigation #page-wrapper, -.body-small.fixed-sidebar.mini-navbar .top-navigation #page-wrapper, -.canvas-menu #page-wrapper { - margin: 0; -} -.top-navigation.fixed-nav #wrapper, -.fixed-nav #wrapper.top-navigation { - margin-top: 50px; -} -.top-navigation .footer.fixed { - margin-left: 0 !important; -} -.top-navigation .wrapper.wrapper-content { - padding: 40px; -} -.top-navigation.body-small .wrapper.wrapper-content, -.body-small .top-navigation .wrapper.wrapper-content { - padding: 40px 0 40px 0; -} -.navbar-toggle { - background-color: #007C82; - color: #fff; - padding: 6px 12px; - font-size: 14px; -} -.top-navigation .navbar-nav .open .dropdown-menu > li > a, -.top-navigation .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 10px 15px 10px 20px; -} -@media (max-width: 768px) { - .top-navigation .navbar-header { - display: block; - float: none; - } -} -.menu-visible-lg, -.menu-visible-md { - display: none !important; -} -@media (min-width: 1200px) { - .menu-visible-lg { - display: block !important; - } -} -@media (min-width: 992px) { - .menu-visible-md { - display: block !important; - } -} -@media (max-width: 767px) { - .menu-visible-md { - display: block !important; - } - .menu-visible-lg { - display: block !important; - } -} -.btn { - border-radius: 3px; -} -.float-e-margins .btn { - margin-bottom: 5px; -} -.btn-w-m { - min-width: 120px; -} -.btn-primary.btn-outline { - color: #007C82; -} -.btn-success.btn-outline { - color: #1c84c6; -} -.btn-info.btn-outline { - color: #23c6c8; -} -.btn-warning.btn-outline { - color: #f8ac59; -} -.btn-danger.btn-outline { - color: #ed5565; -} -.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; -} -.btn-primary { - background-color: #007C82; - border-color: #007C82; - color: #FFFFFF; -} -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary, -.btn-primary:active:focus, -.btn-primary:active:hover, -.btn-primary.active:hover, -.btn-primary.active:focus { - background-color: #18a689; - border-color: #18a689; - color: #FFFFFF; -} -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled, -.btn-primary.disabled:hover, -.btn-primary.disabled:focus, -.btn-primary.disabled:active, -.btn-primary.disabled.active, -.btn-primary[disabled], -.btn-primary[disabled]:hover, -.btn-primary[disabled]:focus, -.btn-primary[disabled]:active, -.btn-primary.active[disabled], -fieldset[disabled] .btn-primary, -fieldset[disabled] .btn-primary:hover, -fieldset[disabled] .btn-primary:focus, -fieldset[disabled] .btn-primary:active, -fieldset[disabled] .btn-primary.active { - background-color: #1dc5a3; - border-color: #1dc5a3; -} -.btn-success { - background-color: #1c84c6; - border-color: #1c84c6; - color: #FFFFFF; -} -.btn-success:hover, -.btn-success:focus, -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success, -.btn-success:active:focus, -.btn-success:active:hover, -.btn-success.active:hover, -.btn-success.active:focus { - background-color: #1a7bb9; - border-color: #1a7bb9; - color: #FFFFFF; -} -.btn-success:active, -.btn-success.active, -.open .dropdown-toggle.btn-success { - background-image: none; -} -.btn-success.disabled, -.btn-success.disabled:hover, -.btn-success.disabled:focus, -.btn-success.disabled:active, -.btn-success.disabled.active, -.btn-success[disabled], -.btn-success[disabled]:hover, -.btn-success[disabled]:focus, -.btn-success[disabled]:active, -.btn-success.active[disabled], -fieldset[disabled] .btn-success, -fieldset[disabled] .btn-success:hover, -fieldset[disabled] .btn-success:focus, -fieldset[disabled] .btn-success:active, -fieldset[disabled] .btn-success.active { - background-color: #1f90d8; - border-color: #1f90d8; -} -.btn-info { - background-color: #23c6c8; - border-color: #23c6c8; - color: #FFFFFF; -} -.btn-info:hover, -.btn-info:focus, -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info, -.btn-info:active:focus, -.btn-info:active:hover, -.btn-info.active:hover, -.btn-info.active:focus { - background-color: #21b9bb; - border-color: #21b9bb; - color: #FFFFFF; -} -.btn-info:active, -.btn-info.active, -.open .dropdown-toggle.btn-info { - background-image: none; -} -.btn-info.disabled, -.btn-info.disabled:hover, -.btn-info.disabled:focus, -.btn-info.disabled:active, -.btn-info.disabled.active, -.btn-info[disabled], -.btn-info[disabled]:hover, -.btn-info[disabled]:focus, -.btn-info[disabled]:active, -.btn-info.active[disabled], -fieldset[disabled] .btn-info, -fieldset[disabled] .btn-info:hover, -fieldset[disabled] .btn-info:focus, -fieldset[disabled] .btn-info:active, -fieldset[disabled] .btn-info.active { - background-color: #26d7d9; - border-color: #26d7d9; -} -.btn-default { - color: inherit; - background: white; - border: 1px solid #e7eaec; -} -.btn-default:hover, -.btn-default:focus, -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default, -.btn-default:active:focus, -.btn-default:active:hover, -.btn-default.active:hover, -.btn-default.active:focus { - color: inherit; - border: 1px solid #d2d2d2; -} -.btn-default:active, -.btn-default.active, -.open .dropdown-toggle.btn-default { - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15) inset; -} -.btn-default.disabled, -.btn-default.disabled:hover, -.btn-default.disabled:focus, -.btn-default.disabled:active, -.btn-default.disabled.active, -.btn-default[disabled], -.btn-default[disabled]:hover, -.btn-default[disabled]:focus, -.btn-default[disabled]:active, -.btn-default.active[disabled], -fieldset[disabled] .btn-default, -fieldset[disabled] .btn-default:hover, -fieldset[disabled] .btn-default:focus, -fieldset[disabled] .btn-default:active, -fieldset[disabled] .btn-default.active { - color: #cacaca; -} -.btn-warning { - background-color: #f8ac59; - border-color: #f8ac59; - color: #FFFFFF; -} -.btn-warning:hover, -.btn-warning:focus, -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning, -.btn-warning:active:focus, -.btn-warning:active:hover, -.btn-warning.active:hover, -.btn-warning.active:focus { - background-color: #f7a54a; - border-color: #f7a54a; - color: #FFFFFF; -} -.btn-warning:active, -.btn-warning.active, -.open .dropdown-toggle.btn-warning { - background-image: none; -} -.btn-warning.disabled, -.btn-warning.disabled:hover, -.btn-warning.disabled:focus, -.btn-warning.disabled:active, -.btn-warning.disabled.active, -.btn-warning[disabled], -.btn-warning[disabled]:hover, -.btn-warning[disabled]:focus, -.btn-warning[disabled]:active, -.btn-warning.active[disabled], -fieldset[disabled] .btn-warning, -fieldset[disabled] .btn-warning:hover, -fieldset[disabled] .btn-warning:focus, -fieldset[disabled] .btn-warning:active, -fieldset[disabled] .btn-warning.active { - background-color: #f9b66d; - border-color: #f9b66d; -} -.btn-danger { - background-color: #ed5565; - border-color: #ed5565; - color: #FFFFFF; -} -.btn-danger:hover, -.btn-danger:focus, -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger, -.btn-danger:active:focus, -.btn-danger:active:hover, -.btn-danger.active:hover, -.btn-danger.active:focus { - background-color: #ec4758; - border-color: #ec4758; - color: #FFFFFF; -} -.btn-danger:active, -.btn-danger.active, -.open .dropdown-toggle.btn-danger { - background-image: none; -} -.btn-danger.disabled, -.btn-danger.disabled:hover, -.btn-danger.disabled:focus, -.btn-danger.disabled:active, -.btn-danger.disabled.active, -.btn-danger[disabled], -.btn-danger[disabled]:hover, -.btn-danger[disabled]:focus, -.btn-danger[disabled]:active, -.btn-danger.active[disabled], -fieldset[disabled] .btn-danger, -fieldset[disabled] .btn-danger:hover, -fieldset[disabled] .btn-danger:focus, -fieldset[disabled] .btn-danger:active, -fieldset[disabled] .btn-danger.active { - background-color: #ef6776; - border-color: #ef6776; -} -.btn-link { - color: inherit; -} -.btn-link:hover, -.btn-link:focus, -.btn-link:active, -.btn-link.active, -.open .dropdown-toggle.btn-link { - color: #007C82; - text-decoration: none; -} -.btn-link:active, -.btn-link.active, -.open .dropdown-toggle.btn-link { - background-image: none; -} -.btn-link.disabled, -.btn-link.disabled:hover, -.btn-link.disabled:focus, -.btn-link.disabled:active, -.btn-link.disabled.active, -.btn-link[disabled], -.btn-link[disabled]:hover, -.btn-link[disabled]:focus, -.btn-link[disabled]:active, -.btn-link.active[disabled], -fieldset[disabled] .btn-link, -fieldset[disabled] .btn-link:hover, -fieldset[disabled] .btn-link:focus, -fieldset[disabled] .btn-link:active, -fieldset[disabled] .btn-link.active { - color: #cacaca; -} -.btn-white { - color: inherit; - background: white; - border: 1px solid #e7eaec; -} -.btn-white:hover, -.btn-white:focus, -.btn-white:active, -.btn-white.active, -.open .dropdown-toggle.btn-white, -.btn-white:active:focus, -.btn-white:active:hover, -.btn-white.active:hover, -.btn-white.active:focus { - color: inherit; - border: 1px solid #d2d2d2; -} -.btn-white:active, -.btn-white.active { - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15) inset; -} -.btn-white:active, -.btn-white.active, -.open .dropdown-toggle.btn-white { - background-image: none; -} -.btn-white.disabled, -.btn-white.disabled:hover, -.btn-white.disabled:focus, -.btn-white.disabled:active, -.btn-white.disabled.active, -.btn-white[disabled], -.btn-white[disabled]:hover, -.btn-white[disabled]:focus, -.btn-white[disabled]:active, -.btn-white.active[disabled], -fieldset[disabled] .btn-white, -fieldset[disabled] .btn-white:hover, -fieldset[disabled] .btn-white:focus, -fieldset[disabled] .btn-white:active, -fieldset[disabled] .btn-white.active { - color: #cacaca; -} -.form-control, -.form-control:focus, -.has-error .form-control:focus, -.has-success .form-control:focus, -.has-warning .form-control:focus, -.navbar-collapse, -.navbar-form, -.navbar-form-custom .form-control:focus, -.navbar-form-custom .form-control:hover, -.open .btn.dropdown-toggle, -.panel, -.popover, -.progress, -.progress-bar { - box-shadow: none; -} -.btn-outline { - color: inherit; - background-color: transparent; - transition: all .5s; -} -.btn-rounded { - border-radius: 50px; -} -.btn-large-dim { - width: 90px; - height: 90px; - font-size: 42px; -} -button.dim { - display: inline-block; - text-decoration: none; - text-transform: uppercase; - text-align: center; - padding-top: 6px; - margin-right: 10px; - position: relative; - cursor: pointer; - border-radius: 5px; - font-weight: 600; - margin-bottom: 20px !important; -} -button.dim:active { - top: 3px; -} -button.btn-primary.dim { - box-shadow: inset 0 0 0 #16987e, 0 5px 0 0 #16987e, 0 10px 5px #999999; -} -button.btn-primary.dim:active { - box-shadow: inset 0 0 0 #16987e, 0 2px 0 0 #16987e, 0 5px 3px #999999; -} -button.btn-default.dim { - box-shadow: inset 0 0 0 #b3b3b3, 0 5px 0 0 #b3b3b3, 0 10px 5px #999999; -} -button.btn-default.dim:active { - box-shadow: inset 0 0 0 #b3b3b3, 0 2px 0 0 #b3b3b3, 0 5px 3px #999999; -} -button.btn-warning.dim { - box-shadow: inset 0 0 0 #f79d3c, 0 5px 0 0 #f79d3c, 0 10px 5px #999999; -} -button.btn-warning.dim:active { - box-shadow: inset 0 0 0 #f79d3c, 0 2px 0 0 #f79d3c, 0 5px 3px #999999; -} -button.btn-info.dim { - box-shadow: inset 0 0 0 #1eacae, 0 5px 0 0 #1eacae, 0 10px 5px #999999; -} -button.btn-info.dim:active { - box-shadow: inset 0 0 0 #1eacae, 0 2px 0 0 #1eacae, 0 5px 3px #999999; -} -button.btn-success.dim { - box-shadow: inset 0 0 0 #1872ab, 0 5px 0 0 #1872ab, 0 10px 5px #999999; -} -button.btn-success.dim:active { - box-shadow: inset 0 0 0 #1872ab, 0 2px 0 0 #1872ab, 0 5px 3px #999999; -} -button.btn-danger.dim { - box-shadow: inset 0 0 0 #ea394c, 0 5px 0 0 #ea394c, 0 10px 5px #999999; -} -button.btn-danger.dim:active { - box-shadow: inset 0 0 0 #ea394c, 0 2px 0 0 #ea394c, 0 5px 3px #999999; -} -button.dim:before { - font-size: 50px; - line-height: 1em; - font-weight: normal; - color: #fff; - display: block; - padding-top: 10px; -} -button.dim:active:before { - top: 7px; - font-size: 50px; -} -.btn:focus { - outline: none !important; -} -.label { - background-color: #d1dade; - color: #5e5e5e; - font-family: 'Open Sans', Gadget, sans-serif; - font-size: 10px; - font-weight: 600; - padding: 3px 8px; - text-shadow: none; -} -.badge { - background-color: #d1dade; - color: #5e5e5e; - font-family: 'Open Sans', Gadget, sans-serif; - font-size: 11px; - font-weight: 600; - padding-bottom: 4px; - padding-left: 6px; - padding-right: 6px; - text-shadow: none; -} -.label-primary, -.badge-primary { - background-color: #007C82; - color: #FFFFFF; -} -.label-success, -.badge-success { - background-color: #1c84c6; - color: #FFFFFF; -} -.label-warning, -.badge-warning { - background-color: #f8ac59; - color: #FFFFFF; -} -.label-warning-light, -.badge-warning-light { - background-color: #f8ac59; - color: #ffffff; -} -.label-danger, -.badge-danger { - background-color: #ed5565; - color: #FFFFFF; -} -.label-info, -.badge-info { - background-color: #23c6c8; - color: #FFFFFF; -} -.label-inverse, -.badge-inverse { - background-color: #262626; - color: #FFFFFF; -} -.label-white, -.badge-white { - background-color: #FFFFFF; - color: #5E5E5E; -} -.label-white, -.badge-disable { - background-color: #2A2E36; - color: #8B91A0; -} -/* TOOGLE SWICH */ -.onoffswitch { - position: relative; - width: 64px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; -} -.onoffswitch-checkbox { - display: none; -} -.onoffswitch-label { - display: block; - overflow: hidden; - cursor: pointer; - border: 2px solid #007C82; - border-radius: 2px; -} -.onoffswitch-inner { - width: 200%; - margin-left: -100%; - -moz-transition: margin 0.3s ease-in 0s; - -webkit-transition: margin 0.3s ease-in 0s; - -o-transition: margin 0.3s ease-in 0s; - transition: margin 0.3s ease-in 0s; -} -.onoffswitch-inner:before, -.onoffswitch-inner:after { - float: left; - width: 50%; - height: 20px; - padding: 0; - line-height: 20px; - font-size: 12px; - color: white; - font-family: Trebuchet, Arial, sans-serif; - font-weight: bold; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.onoffswitch-inner:before { - content: "ON"; - padding-left: 10px; - background-color: #007C82; - color: #FFFFFF; -} -.onoffswitch-inner:after { - content: "OFF"; - padding-right: 10px; - background-color: #FFFFFF; - color: #999999; - text-align: right; -} -.onoffswitch-switch { - width: 20px; - margin: 0; - background: #FFFFFF; - border: 2px solid #007C82; - border-radius: 2px; - position: absolute; - top: 0; - bottom: 0; - right: 44px; - -moz-transition: all 0.3s ease-in 0s; - -webkit-transition: all 0.3s ease-in 0s; - -o-transition: all 0.3s ease-in 0s; - transition: all 0.3s ease-in 0s; -} -.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { - margin-left: 0; -} -.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { - right: 0; -} -/* CHOSEN PLUGIN */ -.chosen-container-single .chosen-single { - background: #ffffff; - box-shadow: none; - -moz-box-sizing: border-box; - background-color: #FFFFFF; - border: 1px solid #CBD5DD; - border-radius: 2px; - cursor: text; - height: auto !important; - margin: 0; - min-height: 30px; - overflow: hidden; - padding: 4px 12px; - position: relative; - width: 100%; -} -.chosen-container-multi .chosen-choices li.search-choice { - background: #f1f1f1; - border: 1px solid #ededed; - border-radius: 2px; - box-shadow: none; - color: #333333; - cursor: default; - line-height: 13px; - margin: 3px 0 3px 5px; - padding: 3px 20px 3px 5px; - position: relative; -} -/* PAGINATIN */ -.pagination > .active > a, -.pagination > .active > span, -.pagination > .active > a:hover, -.pagination > .active > span:hover, -.pagination > .active > a:focus, -.pagination > .active > span:focus { - background-color: #f4f4f4; - border-color: #DDDDDD; - color: inherit; - cursor: default; - z-index: 2; -} -.pagination > li > a, -.pagination > li > span { - background-color: #FFFFFF; - border: 1px solid #DDDDDD; - color: inherit; - float: left; - line-height: 1.42857; - margin-left: -1px; - padding: 4px 10px; - position: relative; - text-decoration: none; -} -/* TOOLTIPS */ -.tooltip-inner { - background-color: #2F4050; -} -.tooltip.top .tooltip-arrow { - border-top-color: #2F4050; -} -.tooltip.right .tooltip-arrow { - border-right-color: #2F4050; -} -.tooltip.bottom .tooltip-arrow { - border-bottom-color: #2F4050; -} -.tooltip.left .tooltip-arrow { - border-left-color: #2F4050; -} -/* EASY PIE CHART*/ -.easypiechart { - position: relative; - text-align: center; -} -.easypiechart .h2 { - margin-left: 10px; - margin-top: 10px; - display: inline-block; -} -.easypiechart canvas { - top: 0; - left: 0; -} -.easypiechart .easypie-text { - line-height: 1; - position: absolute; - top: 33px; - width: 100%; - z-index: 1; -} -.easypiechart img { - margin-top: -4px; -} -.jqstooltip { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -/* FULLCALENDAR */ -.fc-state-default { - background-color: #ffffff; - background-image: none; - background-repeat: repeat-x; - box-shadow: none; - color: #333333; - text-shadow: none; -} -.fc-state-default { - border: 1px solid; -} -.fc-button { - color: inherit; - border: 1px solid #e7eaec; - cursor: pointer; - display: inline-block; - height: 1.9em; - line-height: 1.9em; - overflow: hidden; - padding: 0 0.6em; - position: relative; - white-space: nowrap; -} -.fc-state-active { - background-color: #007C82; - border-color: #007C82; - color: #ffffff; -} -.fc-header-title h2 { - font-size: 16px; - font-weight: 600; - color: inherit; -} -.fc-content .fc-widget-header, -.fc-content .fc-widget-content { - border-color: #e7eaec; - font-weight: normal; -} -.fc-border-separate tbody { - background-color: #F8F8F8; -} -.fc-state-highlight { - background: none repeat scroll 0 0 #FCF8E3; -} -.external-event { - padding: 5px 10px; - border-radius: 2px; - cursor: pointer; - margin-bottom: 5px; -} -.fc-ltr .fc-event-hori.fc-event-end, -.fc-rtl .fc-event-hori.fc-event-start { - border-radius: 2px; -} -.fc-event, -.fc-agenda .fc-event-time, -.fc-event a { - padding: 4px 6px; - background-color: #007C82; - /* background color */ - border-color: #007C82; - /* border color */ -} -.fc-event-time, -.fc-event-title { - color: #717171; - padding: 0 1px; -} -.ui-calendar .fc-event-time, -.ui-calendar .fc-event-title { - color: #fff; -} -/* Chat */ -.chat-activity-list .chat-element { - border-bottom: 1px solid #e7eaec; -} -.chat-element:first-child { - margin-top: 0; -} -.chat-element { - padding-bottom: 15px; -} -.chat-element, -.chat-element .media { - margin-top: 15px; -} -.chat-element, -.media-body { - overflow: hidden; -} -.media-body { - display: block; - width: auto; -} -.chat-element > .pull-left { - margin-right: 10px; -} -.chat-element img.img-circle, -.dropdown-messages-box img.img-circle { - width: 38px; - height: 38px; -} -.chat-element .well { - border: 1px solid #e7eaec; - box-shadow: none; - margin-top: 10px; - margin-bottom: 5px; - padding: 10px 20px; - font-size: 11px; - line-height: 16px; -} -.chat-element .actions { - margin-top: 10px; -} -.chat-element .photos { - margin: 10px 0; -} -.right.chat-element > .pull-right { - margin-left: 10px; -} -.chat-photo { - max-height: 180px; - border-radius: 4px; - overflow: hidden; - margin-right: 10px; - margin-bottom: 10px; -} -.chat { - margin: 0; - padding: 0; - list-style: none; -} -.chat li { - margin-bottom: 10px; - padding-bottom: 5px; - border-bottom: 1px dotted #B3A9A9; -} -.chat li.left .chat-body { - margin-left: 60px; -} -.chat li.right .chat-body { - margin-right: 60px; -} -.chat li .chat-body p { - margin: 0; - color: #777777; -} -.panel .slidedown .glyphicon, -.chat .glyphicon { - margin-right: 5px; -} -.chat-panel .panel-body { - height: 350px; - overflow-y: scroll; -} -/* LIST GROUP */ -a.list-group-item.active, -a.list-group-item.active:hover, -a.list-group-item.active:focus { - background-color: #007C82; - border-color: #007C82; - color: #FFFFFF; - z-index: 2; -} -.list-group-item-heading { - margin-top: 10px; -} -.list-group-item-text { - margin: 0 0 10px; - color: inherit; - font-size: 12px; - line-height: inherit; -} -.no-padding .list-group-item { - border-left: none; - border-right: none; - border-bottom: none; -} -.no-padding .list-group-item:first-child { - border-left: none; - border-right: none; - border-bottom: none; - border-top: none; -} -.no-padding .list-group { - margin-bottom: 0; -} -.list-group-item { - background-color: inherit; - border: 1px solid #e7eaec; - display: block; - margin-bottom: -1px; - padding: 10px 15px; - position: relative; -} -.elements-list .list-group-item { - border-left: none; - border-right: none; - padding: 15px 25px; -} -.elements-list .list-group-item:first-child { - border-left: none; - border-right: none; - border-top: none !important; -} -.elements-list .list-group { - margin-bottom: 0; -} -.elements-list a { - color: inherit; -} -.elements-list .list-group-item.active, -.elements-list .list-group-item:hover { - background: #f3f3f4; - color: inherit; - border-color: #e7eaec; - /*border-bottom: 1px solid #e7eaec;*/ - /*border-top: 1px solid #e7eaec;*/ - border-radius: 0; -} -.elements-list li.active { - transition: none; -} -.element-detail-box { - padding: 25px; -} -/* FLOT CHART */ -.flot-chart { - display: block; - height: 200px; -} -.widget .flot-chart.dashboard-chart { - display: block; - height: 120px; - margin-top: 40px; -} -.flot-chart.dashboard-chart { - display: block; - height: 180px; - margin-top: 40px; -} -.flot-chart-content { - width: 100%; - height: 100%; -} -.flot-chart-pie-content { - width: 200px; - height: 200px; - margin: auto; -} -.jqstooltip { - position: absolute; - display: block; - left: 0; - top: 0; - visibility: hidden; - background: #2b303a; - background-color: rgba(43, 48, 58, 0.8); - color: white; - text-align: left; - white-space: nowrap; - z-index: 10000; - padding: 5px 5px 5px 5px; - min-height: 22px; - border-radius: 3px; -} -.jqsfield { - color: white; - text-align: left; -} -.fh-150 { - height: 150px; -} -.fh-200 { - height: 200px; -} -.h-150 { - min-height: 150px; -} -.h-200 { - min-height: 200px; -} -.legendLabel { - padding-left: 5px; -} -.stat-list li:first-child { - margin-top: 0; -} -.stat-list { - list-style: none; - padding: 0; - margin: 0; -} -.stat-percent { - float: right; -} -.stat-list li { - margin-top: 15px; - position: relative; -} -/* DATATABLES */ -table.dataTable thead .sorting, -table.dataTable thead .sorting_asc:after, -table.dataTable thead .sorting_desc, -table.dataTable thead .sorting_asc_disabled, -table.dataTable thead .sorting_desc_disabled { - background: transparent; -} -.dataTables_wrapper { - padding-bottom: 30px; -} -.dataTables_length { - float: left; -} -.dataTables_filter label { - margin-right: 5px; -} -.html5buttons { - float: right; -} -.html5buttons a { - border: 1px solid #e7eaec; - background: #fff; - color: #676a6c; - box-shadow: none; - padding: 6px 8px; - font-size: 12px; -} -.html5buttons a:hover, -.html5buttons a:focus:active { - background-color: #eee; - color: inherit; - border-color: #d2d2d2; -} -div.dt-button-info { - z-index: 100; -} -@media (max-width: 768px) { - .html5buttons { - float: none; - margin-top: 10px; - } - .dataTables_length { - float: none; - } -} -/* CIRCLE */ -.img-circle { - border-radius: 50%; -} -.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; -} -/* ANIMATION */ -.css-animation-box h1 { - font-size: 44px; -} -.animation-efect-links a { - padding: 4px 6px; - font-size: 12px; -} -#animation_box { - background-color: #f9f8f8; - border-radius: 16px; - width: 80%; - margin: 0 auto; - padding-top: 80px; -} -.animation-text-box { - position: absolute; - margin-top: 40px; - left: 50%; - margin-left: -100px; - width: 200px; -} -.animation-text-info { - position: absolute; - margin-top: -60px; - left: 50%; - margin-left: -100px; - width: 200px; - font-size: 10px; -} -.animation-text-box h2 { - font-size: 54px; - font-weight: 600; - margin-bottom: 5px; -} -.animation-text-box p { - font-size: 12px; - text-transform: uppercase; -} -/* PEACE */ -.pace { - -webkit-pointer-events: none; - pointer-events: none; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; -} -.pace-inactive { - display: none; -} -.pace .pace-progress { - background: #007C82; - position: fixed; - z-index: 2040; - top: 0; - right: 100%; - width: 100%; - height: 2px; -} -.pace-inactive { - display: none; -} -/* WIDGETS */ -.widget { - border-radius: 5px; - padding: 15px 20px; - margin-bottom: 10px; - margin-top: 10px; -} -.widget.style1 h2 { - font-size: 30px; -} -.widget h2, -.widget h3 { - margin-top: 5px; - margin-bottom: 0; -} -.widget-text-box { - padding: 20px; - border: 1px solid #e7eaec; - background: #ffffff; -} -.widget-head-color-box { - border-radius: 5px 5px 0 0; - margin-top: 10px; -} -.widget .flot-chart { - height: 100px; -} -.vertical-align div { - display: inline-block; - vertical-align: middle; -} -.vertical-align h2, -.vertical-align h3 { - margin: 0; -} -.todo-list { - list-style: none outside none; - margin: 0; - padding: 0; - font-size: 14px; -} -.todo-list.small-list { - font-size: 12px; -} -.todo-list.small-list > li { - background: #f3f3f4; - border-left: none; - border-right: none; - border-radius: 4px; - color: inherit; - margin-bottom: 2px; - padding: 6px 6px 6px 12px; -} -.todo-list.small-list .btn-xs, -.todo-list.small-list .btn-group-xs > .btn { - border-radius: 5px; - font-size: 10px; - line-height: 1.5; - padding: 1px 2px 1px 5px; -} -.todo-list > li { - background: #f3f3f4; - border-left: 6px solid #e7eaec; - border-right: 6px solid #e7eaec; - border-radius: 4px; - color: inherit; - margin-bottom: 2px; - padding: 10px; -} -.todo-list .handle { - cursor: move; - display: inline-block; - font-size: 16px; - margin: 0 5px; -} -.todo-list > li .label { - font-size: 9px; - margin-left: 10px; -} -.check-link { - font-size: 16px; -} -.todo-completed { - text-decoration: line-through; -} -.geo-statistic h1 { - font-size: 36px; - margin-bottom: 0; -} -.glyphicon.fa { - font-family: "FontAwesome"; -} -/* INPUTS */ -.inline { - display: inline-block !important; -} -.input-s-sm { - width: 120px; -} -.input-s { - width: 200px; -} -.input-s-lg { - width: 250px; -} -.i-checks { - padding-left: 0; -} -.form-control, -.single-line { - background-color: #FFFFFF; - background-image: none; - border: 1px solid #e5e6e7; - border-radius: 1px; - color: inherit; - display: block; - padding: 6px 12px; - transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; - width: 100%; - font-size: 14px; -} -.form-control:focus, -.single-line:focus { - border-color: #007C82 !important; -} -.has-success .form-control { - border-color: #007C82; -} -.has-warning .form-control { - border-color: #f8ac59; -} -.has-error .form-control { - border-color: #ed5565; -} -.has-success .control-label { - color: #007C82; -} -.has-warning .control-label { - color: #f8ac59; -} -.has-error .control-label { - color: #ed5565; -} -.input-group-addon { - background-color: #fff; - border: 1px solid #E5E6E7; - border-radius: 1px; - color: inherit; - font-size: 14px; - font-weight: 400; - line-height: 1; - padding: 6px 12px; - text-align: center; -} -.spinner-buttons.input-group-btn .btn-xs { - line-height: 1.13; -} -.spinner-buttons.input-group-btn { - width: 20%; -} -.noUi-connect { - background: none repeat scroll 0 0 #007C82; - box-shadow: none; -} -.slider_red .noUi-connect { - background: none repeat scroll 0 0 #ed5565; - box-shadow: none; -} -/* UI Sortable */ -.ui-sortable .ibox-title { - cursor: move; -} -.ui-sortable-placeholder { - border: 1px dashed #cecece !important; - visibility: visible !important; - background: #e7eaec; -} -.ibox.ui-sortable-placeholder { - margin: 0 0 23px !important; -} -/* SWITCHES */ -.onoffswitch { - position: relative; - width: 54px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; -} -.onoffswitch-checkbox { - display: none; -} -.onoffswitch-label { - display: block; - overflow: hidden; - cursor: pointer; - border: 2px solid #007C82; - border-radius: 3px; -} -.onoffswitch-inner { - display: block; - width: 200%; - margin-left: -100%; - -moz-transition: margin 0.3s ease-in 0s; - -webkit-transition: margin 0.3s ease-in 0s; - -o-transition: margin 0.3s ease-in 0s; - transition: margin 0.3s ease-in 0s; -} -.onoffswitch-inner:before, -.onoffswitch-inner:after { - display: block; - float: left; - width: 50%; - height: 16px; - padding: 0; - line-height: 16px; - font-size: 10px; - color: white; - font-family: Trebuchet, Arial, sans-serif; - font-weight: bold; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -.onoffswitch-inner:before { - content: "ON"; - padding-left: 7px; - background-color: #007C82; - color: #FFFFFF; -} -.onoffswitch-inner:after { - content: "OFF"; - padding-right: 7px; - background-color: #FFFFFF; - color: #919191; - text-align: right; -} -.onoffswitch-switch { - display: block; - width: 18px; - margin: 0; - background: #FFFFFF; - border: 2px solid #007C82; - border-radius: 3px; - position: absolute; - top: 0; - bottom: 0; - right: 36px; - -moz-transition: all 0.3s ease-in 0s; - -webkit-transition: all 0.3s ease-in 0s; - -o-transition: all 0.3s ease-in 0s; - transition: all 0.3s ease-in 0s; -} -.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner { - margin-left: 0; -} -.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch { - right: 0; -} -/* jqGrid */ -.ui-jqgrid { - -moz-box-sizing: content-box; -} -.ui-jqgrid-btable { - border-collapse: separate; -} -.ui-jqgrid-htable { - border-collapse: separate; -} -.ui-jqgrid-titlebar { - height: 40px; - line-height: 15px; - color: #676a6c; - background-color: #F9F9F9; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.ui-jqgrid .ui-jqgrid-title { - float: left; - margin: 1.1em 1em 0.2em; -} -.ui-jqgrid .ui-jqgrid-titlebar { - position: relative; - border-left: 0 solid; - border-right: 0 solid; - border-top: 0 solid; -} -.ui-widget-header { - background: none; - background-image: none; - background-color: #f5f5f6; - text-transform: uppercase; - border-top-left-radius: 0; - border-top-right-radius: 0; -} -.ui-jqgrid tr.ui-row-ltr td { - border-right-color: inherit; - border-right-style: solid; - border-right-width: 1px; - text-align: left; - border-color: #DDDDDD; - background-color: inherit; -} -.ui-search-toolbar input[type="text"] { - font-size: 12px; - height: 15px; - border: 1px solid #CCCCCC; - border-radius: 0; -} -.ui-state-default, -.ui-widget-content .ui-state-default, -.ui-widget-header .ui-state-default { - background: #F9F9F9; - border: 1px solid #DDDDDD; - line-height: 15px; - font-weight: bold; - color: #676a6c; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); -} -.ui-widget-content { - box-sizing: content-box; -} -.ui-icon-triangle-1-n { - background-position: 1px -16px; -} -.ui-jqgrid tr.ui-search-toolbar th { - border-top-width: 0 !important; - border-top-color: inherit !important; - border-top-style: ridge !important; -} -.ui-state-hover, -.ui-widget-content .ui-state-hover, -.ui-state-focus, -.ui-widget-content .ui-state-focus, -.ui-widget-header .ui-state-focus { - background: #f5f5f5; - border-collapse: separate; -} -.ui-state-highlight, -.ui-widget-content .ui-state-highlight, -.ui-widget-header .ui-state-highlight { - background: #f2fbff; -} -.ui-state-active, -.ui-widget-content .ui-state-active, -.ui-widget-header .ui-state-active { - border: 1px solid #dddddd; - background: #ffffff; - font-weight: normal; - color: #212121; -} -.ui-jqgrid .ui-pg-input { - font-size: inherit; - width: 50px; - border: 1px solid #CCCCCC; - height: 15px; -} -.ui-jqgrid .ui-pg-selbox { - display: block; - font-size: 1em; - height: 25px; - line-height: 18px; - margin: 0; - width: auto; -} -.ui-jqgrid .ui-pager-control { - position: relative; -} -.ui-jqgrid .ui-jqgrid-pager { - height: 32px; - position: relative; -} -.ui-pg-table .navtable .ui-corner-all { - border-radius: 0; -} -.ui-jqgrid .ui-pg-button:hover { - padding: 1px; - border: 0; -} -.ui-jqgrid .loading { - position: absolute; - top: 45%; - left: 45%; - width: auto; - height: auto; - z-index: 101; - padding: 6px; - margin: 5px; - text-align: center; - font-weight: bold; - display: none; - border-width: 2px !important; - font-size: 11px; -} -.ui-jqgrid .form-control { - height: 10px; - width: auto; - display: inline; - padding: 10px 12px; -} -.ui-jqgrid-pager { - height: 32px; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-left, -.ui-corner-tl { - border-top-left-radius: 0; -} -.ui-corner-all, -.ui-corner-top, -.ui-corner-right, -.ui-corner-tr { - border-top-right-radius: 0; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-left, -.ui-corner-bl { - border-bottom-left-radius: 0; -} -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - border-bottom-right-radius: 0; -} -.ui-widget-content { - border: 1px solid #ddd; -} -.ui-jqgrid .ui-jqgrid-titlebar { - padding: 0; -} -.ui-jqgrid .ui-jqgrid-titlebar { - border-bottom: 1px solid #ddd; -} -.ui-jqgrid tr.jqgrow td { - padding: 6px; -} -.ui-jqdialog .ui-jqdialog-titlebar { - padding: 10px 10px; -} -.ui-jqdialog .ui-jqdialog-title { - float: none !important; -} -.ui-jqdialog > .ui-resizable-se { - position: absolute; -} -/* Nestable list */ -.dd { - position: relative; - display: block; - margin: 0; - padding: 0; - list-style: none; - font-size: 13px; - line-height: 20px; -} -.dd-list { - display: block; - position: relative; - margin: 0; - padding: 0; - list-style: none; -} -.dd-list .dd-list { - padding-left: 30px; -} -.dd-collapsed .dd-list { - display: none; -} -.dd-item, -.dd-empty, -.dd-placeholder { - display: block; - position: relative; - margin: 0; - padding: 0; - min-height: 20px; - font-size: 13px; - line-height: 20px; -} -.dd-handle { - display: block; - margin: 5px 0; - padding: 5px 10px; - color: #333; - text-decoration: none; - border: 1px solid #e7eaec; - background: #f5f5f5; - -webkit-border-radius: 3px; - border-radius: 3px; - box-sizing: border-box; - -moz-box-sizing: border-box; -} -.dd-handle span { - font-weight: bold; -} -.dd-handle:hover { - background: #f0f0f0; - cursor: pointer; - font-weight: bold; -} -.dd-item > button { - display: block; - position: relative; - cursor: pointer; - float: left; - width: 25px; - height: 20px; - margin: 5px 0; - padding: 0; - text-indent: 100%; - white-space: nowrap; - overflow: hidden; - border: 0; - background: transparent; - font-size: 12px; - line-height: 1; - text-align: center; - font-weight: bold; -} -.dd-item > button:before { - content: '+'; - display: block; - position: absolute; - width: 100%; - text-align: center; - text-indent: 0; -} -.dd-item > button[data-action="collapse"]:before { - content: '-'; -} -#nestable2 .dd-item > button { - font-family: FontAwesome; - height: 34px; - width: 33px; - color: #c1c1c1; -} -#nestable2 .dd-item > button:before { - content: "\f067"; -} -#nestable2 .dd-item > button[data-action="collapse"]:before { - content: "\f068"; -} -.dd-placeholder, -.dd-empty { - margin: 5px 0; - padding: 0; - min-height: 30px; - background: #f2fbff; - border: 1px dashed #b6bcbf; - box-sizing: border-box; - -moz-box-sizing: border-box; -} -.dd-empty { - border: 1px dashed #bbb; - min-height: 100px; - background-color: #e5e5e5; - background-image: -webkit-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), -webkit-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff); - background-image: -moz-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), -moz-linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff); - background-image: linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff), linear-gradient(45deg, #ffffff 25%, transparent 25%, transparent 75%, #ffffff 75%, #ffffff); - background-size: 60px 60px; - background-position: 0 0, 30px 30px; -} -.dd-dragel { - position: absolute; - z-index: 9999; - pointer-events: none; -} -.dd-dragel > .dd-item .dd-handle { - margin-top: 0; -} -.dd-dragel .dd-handle { - -webkit-box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1); - box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1); -} -/** -* Nestable Extras -*/ -.nestable-lists { - display: block; - clear: both; - padding: 30px 0; - width: 100%; - border: 0; - border-top: 2px solid #ddd; - border-bottom: 2px solid #ddd; -} -#nestable-menu { - padding: 0; - margin: 10px 0 20px 0; -} -#nestable-output, -#nestable2-output { - width: 100%; - font-size: 0.75em; - line-height: 1.333333em; - font-family: open sans, lucida grande, lucida sans unicode, helvetica, arial, sans-serif; - padding: 5px; - box-sizing: border-box; - -moz-box-sizing: border-box; -} -#nestable2 .dd-handle { - color: inherit; - border: 1px dashed #e7eaec; - background: #f3f3f4; - padding: 10px; -} -#nestable2 .dd-handle:hover { - /*background: #bbb;*/ -} -#nestable2 span.label { - margin-right: 10px; -} -#nestable-output, -#nestable2-output { - font-size: 12px; - padding: 25px; - box-sizing: border-box; - -moz-box-sizing: border-box; -} -/* CodeMirror */ -.CodeMirror { - border: 1px solid #eee; - height: auto; -} -.CodeMirror-scroll { - overflow-y: hidden; - overflow-x: auto; -} -/* Google Maps */ -.google-map { - height: 300px; -} -/* Validation */ -label.error { - color: #cc5965; - display: inline-block; - margin-left: 5px; -} -.form-control.error { - border: 1px dotted #cc5965; -} -/* ngGrid */ -.gridStyle { - border: 1px solid #d4d4d4; - width: 100%; - height: 400px; -} -.gridStyle2 { - border: 1px solid #d4d4d4; - width: 500px; - height: 300px; -} -.ngH eaderCell { - border-right: none; - border-bottom: 1px solid #e7eaec; -} -.ngCell { - border-right: none; -} -.ngTopPanel { - background: #F5F5F6; -} -.ngRow.even { - background: #f9f9f9; -} -.ngRow.selected { - background: #EBF2F1; -} -.ngRow { - border-bottom: 1px solid #e7eaec; -} -.ngCell { - background-color: transparent; -} -.ngHeaderCell { - border-right: none; -} -/* Toastr custom style */ -#toast-container > .toast { - background-image: none !important; -} -#toast-container > .toast:before { - position: fixed; - font-family: FontAwesome; - font-size: 24px; - line-height: 24px; - float: left; - color: #FFF; - padding-right: 0.5em; - margin: auto 0.5em auto -1.5em; -} -#toast-container > .toast-warning:before { - content: "\f0e7"; -} -#toast-container > .toast-error:before { - content: "\f071"; -} -#toast-container > .toast-info:before { - content: "\f005"; -} -#toast-container > .toast-success:before { - content: "\f00C"; -} -#toast-container > div { - -moz-box-shadow: 0 0 3px #999; - -webkit-box-shadow: 0 0 3px #999; - box-shadow: 0 0 3px #999; - opacity: .9; - -ms-filter: alpha(opacity=90); - filter: alpha(opacity=90); -} -#toast-container > :hover { - -moz-box-shadow: 0 0 4px #999; - -webkit-box-shadow: 0 0 4px #999; - box-shadow: 0 0 4px #999; - opacity: 1; - -ms-filter: alpha(opacity=100); - filter: alpha(opacity=100); - cursor: pointer; -} -.toast { - background-color: #007C82; -} -.toast-success { - background-color: #007C82; -} -.toast-error { - background-color: #ed5565; -} -.toast-info { - background-color: #23c6c8; -} -.toast-warning { - background-color: #f8ac59; -} -.toast-top-full-width { - margin-top: 20px; -} -.toast-bottom-full-width { - margin-bottom: 20px; -} -/* Notifie */ -.cg-notify-message.inspinia-notify { - background: #fff; - padding: 0; - box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2); - -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2); - border: none; - margin-top: 30px; - color: inherit; -} -.inspinia-notify.alert-warning { - border-left: 6px solid #f8ac59; -} -.inspinia-notify.alert-success { - border-left: 6px solid #1c84c6; -} -.inspinia-notify.alert-danger { - border-left: 6px solid #ed5565; -} -.inspinia-notify.alert-info { - border-left: 6px solid #007C82; -} -/* Image cropper style */ -.img-container, -.img-preview { - overflow: hidden; - text-align: center; - width: 100%; -} -.img-preview-sm { - height: 130px; - width: 200px; -} -/* Forum styles */ -.forum-post-container .media { - margin: 10px 10px 10px 10px; - padding: 20px 10px 20px 10px; - border-bottom: 1px solid #f1f1f1; -} -.forum-avatar { - float: left; - margin-right: 20px; - text-align: center; - width: 110px; -} -.forum-avatar .img-circle { - height: 48px; - width: 48px; -} -.author-info { - color: #676a6c; - font-size: 11px; - margin-top: 5px; - text-align: center; -} -.forum-post-info { - padding: 9px 12px 6px 12px; - background: #f9f9f9; - border: 1px solid #f1f1f1; -} -.media-body > .media { - background: #f9f9f9; - border-radius: 3px; - border: 1px solid #f1f1f1; -} -.forum-post-container .media-body .photos { - margin: 10px 0; -} -.forum-photo { - max-width: 140px; - border-radius: 3px; -} -.media-body > .media .forum-avatar { - width: 70px; - margin-right: 10px; -} -.media-body > .media .forum-avatar .img-circle { - height: 38px; - width: 38px; -} -.mid-icon { - font-size: 66px; -} -.forum-item { - margin: 10px 0; - padding: 10px 0 20px; - border-bottom: 1px solid #f1f1f1; -} -.views-number { - font-size: 24px; - line-height: 18px; - font-weight: 400; -} -.forum-container, -.forum-post-container { - padding: 30px !important; -} -.forum-item small { - color: #999; -} -.forum-item .forum-sub-title { - color: #999; - margin-left: 50px; -} -.forum-title { - margin: 15px 0 15px 0; -} -.forum-info { - text-align: center; -} -.forum-desc { - color: #999; -} -.forum-icon { - float: left; - width: 30px; - margin-right: 20px; - text-align: center; -} -a.forum-item-title { - color: inherit; - display: block; - font-size: 18px; - font-weight: 600; -} -a.forum-item-title:hover { - color: inherit; -} -.forum-icon .fa { - font-size: 30px; - margin-top: 8px; - color: #9b9b9b; -} -.forum-item.active .fa { - color: #007C82; -} -.forum-item.active a.forum-item-title { - color: #007C82; -} -@media (max-width: 992px) { - .forum-info { - margin: 15px 0 10px 0; - /* Comment this is you want to show forum info in small devices */ - display: none; - } - .forum-desc { - float: none !important; - } -} -/* New Timeline style */ -.vertical-container { - /* this class is used to give a max-width to the element it is applied to, and center it horizontally when it reaches that max-width */ - width: 90%; - max-width: 1170px; - margin: 0 auto; -} -.vertical-container::after { - /* clearfix */ - content: ''; - display: table; - clear: both; -} -#vertical-timeline { - position: relative; - padding: 0; - margin-top: 2em; - margin-bottom: 2em; -} -#vertical-timeline::before { - content: ''; - position: absolute; - top: 0; - left: 18px; - height: 100%; - width: 4px; - background: #f1f1f1; -} -.vertical-timeline-content .btn { - float: right; -} -#vertical-timeline.light-timeline:before { - background: #e7eaec; -} -.dark-timeline .vertical-timeline-content:before { - border-color: transparent #f5f5f5 transparent transparent; -} -.dark-timeline.center-orientation .vertical-timeline-content:before { - border-color: transparent transparent transparent #f5f5f5; -} -.dark-timeline .vertical-timeline-block:nth-child(2n) .vertical-timeline-content:before, -.dark-timeline.center-orientation .vertical-timeline-block:nth-child(2n) .vertical-timeline-content:before { - border-color: transparent #f5f5f5 transparent transparent; -} -.dark-timeline .vertical-timeline-content, -.dark-timeline.center-orientation .vertical-timeline-content { - background: #f5f5f5; -} -@media only screen and (min-width: 1170px) { - #vertical-timeline.center-orientation { - margin-top: 3em; - margin-bottom: 3em; - } - #vertical-timeline.center-orientation:before { - left: 50%; - margin-left: -2px; - } -} -@media only screen and (max-width: 1170px) { - .center-orientation.dark-timeline .vertical-timeline-content:before { - border-color: transparent #f5f5f5 transparent transparent; - } -} -.vertical-timeline-block { - position: relative; - margin: 2em 0; -} -.vertical-timeline-block:after { - content: ""; - display: table; - clear: both; -} -.vertical-timeline-block:first-child { - margin-top: 0; -} -.vertical-timeline-block:last-child { - margin-bottom: 0; -} -@media only screen and (min-width: 1170px) { - .center-orientation .vertical-timeline-block { - margin: 4em 0; - } - .center-orientation .vertical-timeline-block:first-child { - margin-top: 0; - } - .center-orientation .vertical-timeline-block:last-child { - margin-bottom: 0; - } -} -.vertical-timeline-icon { - position: absolute; - top: 0; - left: 0; - width: 40px; - height: 40px; - border-radius: 50%; - font-size: 16px; - border: 3px solid #f1f1f1; - text-align: center; -} -.vertical-timeline-icon i { - display: block; - width: 24px; - height: 24px; - position: relative; - left: 50%; - top: 50%; - margin-left: -12px; - margin-top: -9px; -} -@media only screen and (min-width: 1170px) { - .center-orientation .vertical-timeline-icon { - width: 50px; - height: 50px; - left: 50%; - margin-left: -25px; - -webkit-transform: translateZ(0); - -webkit-backface-visibility: hidden; - font-size: 19px; - } - .center-orientation .vertical-timeline-icon i { - margin-left: -12px; - margin-top: -10px; - } - .center-orientation .cssanimations .vertical-timeline-icon.is-hidden { - visibility: hidden; - } -} -.vertical-timeline-content { - position: relative; - margin-left: 60px; - background: white; - border-radius: 0.25em; - padding: 1em; -} -.vertical-timeline-content:after { - content: ""; - display: table; - clear: both; -} -.vertical-timeline-content h2 { - font-weight: 400; - margin-top: 4px; -} -.vertical-timeline-content p { - margin: 1em 0; - line-height: 1.6; -} -.vertical-timeline-content .vertical-date { - float: left; - font-weight: 500; -} -.vertical-date small { - color: #007C82; - font-weight: 400; -} -.vertical-timeline-content::before { - content: ''; - position: absolute; - top: 16px; - right: 100%; - height: 0; - width: 0; - border: 7px solid transparent; - border-right: 7px solid white; -} -@media only screen and (min-width: 768px) { - .vertical-timeline-content h2 { - font-size: 18px; - } - .vertical-timeline-content p { - font-size: 13px; - } -} -@media only screen and (min-width: 1170px) { - .center-orientation .vertical-timeline-content { - margin-left: 0; - padding: 1.6em; - width: 45%; - } - .center-orientation .vertical-timeline-content::before { - top: 24px; - left: 100%; - border-color: transparent; - border-left-color: white; - } - .center-orientation .vertical-timeline-content .btn { - float: left; - } - .center-orientation .vertical-timeline-content .vertical-date { - position: absolute; - width: 100%; - left: 122%; - top: 2px; - font-size: 14px; - } - .center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content { - float: right; - } - .center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content::before { - top: 24px; - left: auto; - right: 100%; - border-color: transparent; - border-right-color: white; - } - .center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content .btn { - float: right; - } - .center-orientation .vertical-timeline-block:nth-child(even) .vertical-timeline-content .vertical-date { - left: auto; - right: 122%; - text-align: right; - } - .center-orientation .cssanimations .vertical-timeline-content.is-hidden { - visibility: hidden; - } -} -/* Tabs */ -.tabs-container .panel-body { - background: #fff; - border: 1px solid #e7eaec; - border-radius: 2px; - padding: 20px; - position: relative; -} -.tabs-container .nav-tabs > li.active > a, -.tabs-container .nav-tabs > li.active > a:hover, -.tabs-container .nav-tabs > li.active > a:focus { - border: 1px solid #e7eaec; - border-bottom-color: transparent; - background-color: #fff; -} -.tabs-container .nav-tabs > li { - float: left; - margin-bottom: -1px; -} -.tabs-container .tab-pane .panel-body { - border-top: none; -} -.tabs-container .nav-tabs > li.active > a, -.tabs-container .nav-tabs > li.active > a:hover, -.tabs-container .nav-tabs > li.active > a:focus { - border: 1px solid #e7eaec; - border-bottom-color: transparent; -} -.tabs-container .nav-tabs { - border-bottom: 1px solid #e7eaec; -} -.tabs-container .tab-pane .panel-body { - border-top: none; -} -.tabs-container .tabs-left .tab-pane .panel-body, -.tabs-container .tabs-right .tab-pane .panel-body { - border-top: 1px solid #e7eaec; -} -.tabs-container .nav-tabs > li a:hover { - background: transparent; - border-color: transparent; -} -.tabs-container .tabs-below > .nav-tabs, -.tabs-container .tabs-right > .nav-tabs, -.tabs-container .tabs-left > .nav-tabs { - border-bottom: 0; -} -.tabs-container .tabs-left .panel-body { - position: static; -} -.tabs-container .tabs-left > .nav-tabs, -.tabs-container .tabs-right > .nav-tabs { - width: 20%; -} -.tabs-container .tabs-left .panel-body { - width: 80%; - margin-left: 20%; -} -.tabs-container .tabs-right .panel-body { - width: 80%; - margin-right: 20%; -} -.tabs-container .tab-content > .tab-pane, -.tabs-container .pill-content > .pill-pane { - display: none; -} -.tabs-container .tab-content > .active, -.tabs-container .pill-content > .active { - display: block; -} -.tabs-container .tabs-below > .nav-tabs { - border-top: 1px solid #e7eaec; -} -.tabs-container .tabs-below > .nav-tabs > li { - margin-top: -1px; - margin-bottom: 0; -} -.tabs-container .tabs-below > .nav-tabs > li > a { - -webkit-border-radius: 0 0 4px 4px; - -moz-border-radius: 0 0 4px 4px; - border-radius: 0 0 4px 4px; -} -.tabs-container .tabs-below > .nav-tabs > li > a:hover, -.tabs-container .tabs-below > .nav-tabs > li > a:focus { - border-top-color: #e7eaec; - border-bottom-color: transparent; -} -.tabs-container .tabs-left > .nav-tabs > li, -.tabs-container .tabs-right > .nav-tabs > li { - float: none; -} -.tabs-container .tabs-left > .nav-tabs > li > a, -.tabs-container .tabs-right > .nav-tabs > li > a { - min-width: 74px; - margin-right: 0; - margin-bottom: 3px; -} -.tabs-container .tabs-left > .nav-tabs { - float: left; - margin-right: 19px; -} -.tabs-container .tabs-left > .nav-tabs > li > a { - margin-right: -1px; - -webkit-border-radius: 4px 0 0 4px; - -moz-border-radius: 4px 0 0 4px; - border-radius: 4px 0 0 4px; -} -.tabs-container .tabs-left > .nav-tabs .active > a, -.tabs-container .tabs-left > .nav-tabs .active > a:hover, -.tabs-container .tabs-left > .nav-tabs .active > a:focus { - border-color: #e7eaec transparent #e7eaec #e7eaec; - *border-right-color: #ffffff; -} -.tabs-container .tabs-right > .nav-tabs { - float: right; - margin-left: 19px; -} -.tabs-container .tabs-right > .nav-tabs > li > a { - margin-left: -1px; - -webkit-border-radius: 0 4px 4px 0; - -moz-border-radius: 0 4px 4px 0; - border-radius: 0 4px 4px 0; -} -.tabs-container .tabs-right > .nav-tabs .active > a, -.tabs-container .tabs-right > .nav-tabs .active > a:hover, -.tabs-container .tabs-right > .nav-tabs .active > a:focus { - border-color: #e7eaec #e7eaec #e7eaec transparent; - *border-left-color: #ffffff; - z-index: 1; -} -@media (max-width: 767px) { - .tabs-container .nav-tabs > li { - float: none !important; - } - .tabs-container .nav-tabs > li.active > a { - border-bottom: 1px solid #e7eaec !important; - margin: 0; - } -} -/* jsvectormap */ -.jvectormap-container { - width: 100%; - height: 100%; - position: relative; - overflow: hidden; -} -.jvectormap-tip { - position: absolute; - display: none; - border: solid 1px #CDCDCD; - border-radius: 3px; - background: #292929; - color: white; - font-family: sans-serif, Verdana; - font-size: smaller; - padding: 5px; -} -.jvectormap-zoomin, -.jvectormap-zoomout, -.jvectormap-goback { - position: absolute; - left: 10px; - border-radius: 3px; - background: #007C82; - padding: 3px; - color: white; - cursor: pointer; - line-height: 10px; - text-align: center; - box-sizing: content-box; -} -.jvectormap-zoomin, -.jvectormap-zoomout { - width: 10px; - height: 10px; -} -.jvectormap-zoomin { - top: 10px; -} -.jvectormap-zoomout { - top: 30px; -} -.jvectormap-goback { - bottom: 10px; - z-index: 1000; - padding: 6px; -} -.jvectormap-spinner { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - background: center no-repeat url(data:image/gif;base64,R0lGODlhIAAgAPMAAP///wAAAMbGxoSEhLa2tpqamjY2NlZWVtjY2OTk5Ly8vB4eHgQEBAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ/V/nmOM82XiHRLYKhKP1oZmADdEAAAh+QQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY/CZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB+A4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6+Ho7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq+B6QDtuetcaBPnW6+O7wDHpIiK9SaVK5GgV543tzjgGcghAgAh+QQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK++G+w48edZPK+M6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE+G+cD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm+FNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk+aV+oJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0/VNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc+XiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30/iI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE/jiuL04RGEBgwWhShRgQExHBAAh+QQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR+ipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq+E71SRQeyqUToLA7VxF0JDyIQh/MVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY+Yip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd+MFCN6HAAIKgNggY0KtEBAAh+QQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1+vsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d+jYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg+ygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0+bm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h+Kr0SJ8MFihpNbx+4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX+BP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA==); -} -.jvectormap-legend-title { - font-weight: bold; - font-size: 14px; - text-align: center; -} -.jvectormap-legend-cnt { - position: absolute; -} -.jvectormap-legend-cnt-h { - bottom: 0; - right: 0; -} -.jvectormap-legend-cnt-v { - top: 0; - right: 0; -} -.jvectormap-legend { - background: black; - color: white; - border-radius: 3px; -} -.jvectormap-legend-cnt-h .jvectormap-legend { - float: left; - margin: 0 10px 10px 0; - padding: 3px 3px 1px 3px; -} -.jvectormap-legend-cnt-h .jvectormap-legend .jvectormap-legend-tick { - float: left; -} -.jvectormap-legend-cnt-v .jvectormap-legend { - margin: 10px 10px 0 0; - padding: 3px; -} -.jvectormap-legend-cnt-h .jvectormap-legend-tick { - width: 40px; -} -.jvectormap-legend-cnt-h .jvectormap-legend-tick-sample { - height: 15px; -} -.jvectormap-legend-cnt-v .jvectormap-legend-tick-sample { - height: 20px; - width: 20px; - display: inline-block; - vertical-align: middle; -} -.jvectormap-legend-tick-text { - font-size: 12px; -} -.jvectormap-legend-cnt-h .jvectormap-legend-tick-text { - text-align: center; -} -.jvectormap-legend-cnt-v .jvectormap-legend-tick-text { - display: inline-block; - vertical-align: middle; - line-height: 20px; - padding-left: 3px; -} -/*Slick Carousel */ -.slick-prev:before, -.slick-next:before { - color: #007C82 !important; -} -/* Payments */ -.payment-card { - background: #ffffff; - padding: 20px; - margin-bottom: 25px; - border: 1px solid #e7eaec; -} -.payment-icon-big { - font-size: 60px; - color: #d1dade; -} -.payments-method.panel-group .panel + .panel { - margin-top: -1px; -} -.payments-method .panel-heading { - padding: 15px; -} -.payments-method .panel { - border-radius: 0; -} -.payments-method .panel-heading h5 { - margin-bottom: 5px; -} -.payments-method .panel-heading i { - font-size: 26px; -} -/* Select2 custom styles */ -.select2-container--default .select2-selection--single, -.select2-container--default .select2-selection--multiple { - border-color: #e7eaec; -} -/* Tour */ -.tour-tour .btn.btn-default { - background-color: #ffffff; - border: 1px solid #d2d2d2; - color: inherit; -} -.tour-step-backdrop { - z-index: 2101; -} -.tour-backdrop { - z-index: 2100; - opacity: .7; -} -.popover[class*=tour-] { - z-index: 2100; -} -body.tour-open .animated { - animation-fill-mode: initial; -} -/* Resizable */ -.resizable-panels .ibox { - clear: none; - margin: 10px; - float: left; - overflow: hidden; - min-height: 150px; - min-width: 150px; -} -.resizable-panels .ibox .ibox-content { - height: calc(100% - 49px); -} -.ui-resizable-helper { - background: rgba(211, 211, 211, 0.4); -} -/* Wizard step fix */ -.wizard > .content > .body { - position: relative; -} -.sidebard-panel { - width: 220px; - background: #ebebed; - padding: 10px 20px; - position: absolute; - right: 0; -} -.sidebard-panel .feed-element img.img-circle { - width: 32px; - height: 32px; -} -.sidebard-panel .feed-element, -.media-body, -.sidebard-panel p { - font-size: 12px; -} -.sidebard-panel .feed-element { - margin-top: 20px; - padding-bottom: 0; -} -.sidebard-panel .list-group { - margin-bottom: 10px; -} -.sidebard-panel .list-group .list-group-item { - padding: 5px 0; - font-size: 12px; - border: 0; -} -.sidebar-content .wrapper, -.wrapper.sidebar-content { - padding-right: 230px !important; -} -.body-small .sidebar-content .wrapper, -.body-small .wrapper.sidebar-content { - padding-right: 20px !important; -} -#right-sidebar { - background-color: #fff; - border-left: 1px solid #e7eaec; - border-top: 1px solid #e7eaec; - overflow: hidden; - position: fixed; - top: 60px; - width: 260px !important; - z-index: 1009; - bottom: 0; - right: -260px; -} -#right-sidebar.sidebar-open { - right: 0; -} -#right-sidebar.sidebar-open.sidebar-top { - top: 0; - border-top: none; -} -.sidebar-container ul.nav-tabs { - border: none; -} -.sidebar-container ul.nav-tabs.navs-4 li { - width: 25%; -} -.sidebar-container ul.nav-tabs.navs-3 li { - width: 33.3333%; -} -.sidebar-container ul.nav-tabs.navs-2 li { - width: 50%; -} -.sidebar-container ul.nav-tabs li { - border: none; -} -.sidebar-container ul.nav-tabs li a { - border: none; - padding: 12px 10px; - margin: 0; - border-radius: 0; - background: #2f4050; - color: #fff; - text-align: center; - border-right: 1px solid #334556; -} -.sidebar-container ul.nav-tabs li.active a { - border: none; - background: #f9f9f9; - color: #676a6c; - font-weight: bold; -} -.sidebar-container .nav-tabs > li.active > a:hover, -.sidebar-container .nav-tabs > li.active > a:focus { - border: none; -} -.sidebar-container ul.sidebar-list { - margin: 0; - padding: 0; -} -.sidebar-container ul.sidebar-list li { - border-bottom: 1px solid #e7eaec; - padding: 15px 20px; - list-style: none; - font-size: 12px; -} -.sidebar-container .sidebar-message:nth-child(2n+2) { - background: #f9f9f9; -} -.sidebar-container ul.sidebar-list li a { - text-decoration: none; - color: inherit; -} -.sidebar-container .sidebar-content { - padding: 15px 20px; - font-size: 12px; -} -.sidebar-container .sidebar-title { - background: #f9f9f9; - padding: 20px; - border-bottom: 1px solid #e7eaec; -} -.sidebar-container .sidebar-title h3 { - margin-bottom: 3px; - padding-left: 2px; -} -.sidebar-container .tab-content h4 { - margin-bottom: 5px; -} -.sidebar-container .sidebar-message > a > .pull-left { - margin-right: 10px; -} -.sidebar-container .sidebar-message > a { - text-decoration: none; - color: inherit; -} -.sidebar-container .sidebar-message { - padding: 15px 20px; -} -.sidebar-container .sidebar-message .message-avatar { - height: 38px; - width: 38px; - border-radius: 50%; -} -.sidebar-container .setings-item { - padding: 15px 20px; - border-bottom: 1px solid #e7eaec; -} -body { - font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - background-color: #2f4050; - font-size: 13px; - color: #676a6c; - overflow-x: hidden; -} -html, -body { - height: 100%; -} -body.full-height-layout #wrapper, -body.full-height-layout #page-wrapper { - height: 100%; -} -#page-wrapper { - min-height: auto; -} -body.boxed-layout { - -} -/*background: url('patterns/shattered.png');*/ -body.boxed-layout #wrapper { - background-color: #2f4050; - max-width: 1200px; - margin: 0 auto; - -webkit-box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75); - -moz-box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75); - box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.75); -} -.top-navigation.boxed-layout #wrapper, -.boxed-layout #wrapper.top-navigation { - max-width: 1300px !important; -} -.block { - display: block; -} -.clear { - display: block; - overflow: hidden; -} -a { - cursor: pointer; -} -a:hover, -a:focus { - text-decoration: none; -} -.border-bottom { - border-bottom: 1px solid #e7eaec !important; -} -.font-bold { - font-weight: 600; -} -.font-noraml { - font-weight: 400; -} -.text-uppercase { - text-transform: uppercase; -} -.b-r { - border-right: 1px solid #e7eaec; -} -.hr-line-dashed { - border-top: 1px dashed #e7eaec; - color: #ffffff; - background-color: #ffffff; - height: 1px; - margin: 20px 0; -} -.hr-line-solid { - border-bottom: 1px solid #e7eaec; - background-color: rgba(0, 0, 0, 0); - border-style: solid !important; - margin-top: 15px; - margin-bottom: 15px; -} -video { - width: 100% !important; - height: auto !important; -} -/* GALLERY */ -.gallery > .row > div { - margin-bottom: 15px; -} -.fancybox img { - margin-bottom: 5px; - /* Only for demo */ - width: 24%; -} -/* Summernote text editor */ -.note-editor { - height: auto !important; - min-height: 300px; -} -.note-editor.fullscreen { - z-index: 2050; -} -/* MODAL */ -.modal-content { - background-clip: padding-box; - background-color: #FFFFFF; - border: 1px solid rgba(0, 0, 0, 0); - border-radius: 4px; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); - outline: 0 none; - position: relative; -} -.modal-dialog { - z-index: 2200; -} -.modal-body { - padding: 20px 30px 30px 30px; -} -.inmodal .modal-body { - background: #f8fafb; -} -.inmodal .modal-header { - padding: 30px 15px; - text-align: center; -} -.animated.modal.fade .modal-dialog { - -webkit-transform: none; - -ms-transform: none; - -o-transform: none; - transform: none; -} -.inmodal .modal-title { - font-size: 26px; -} -.inmodal .modal-icon { - font-size: 84px; - color: #e2e3e3; -} -.modal-footer { - margin-top: 0; -} -/* WRAPPERS */ -#wrapper { - width: 100%; - overflow-x: hidden; -} -.wrapper { - padding: 0 20px; -} -.wrapper-content { - padding: 20px 10px 40px; -} -#page-wrapper { - padding: 0 15px; - min-height: 568px; - position: relative !important; -} -@media (min-width: 768px) { - #page-wrapper { - position: inherit; - margin: 0 0 0 240px; - min-height: 2002px; - } -} -.title-action { - text-align: right; - padding-top: 30px; -} -.ibox-content h1, -.ibox-content h2, -.ibox-content h3, -.ibox-content h4, -.ibox-content h5, -.ibox-title h1, -.ibox-title h2, -.ibox-title h3, -.ibox-title h4, -.ibox-title h5 { - margin-top: 5px; -} -ul.unstyled, -ol.unstyled { - list-style: none outside none; - margin-left: 0; -} -.big-icon { - font-size: 160px !important; - color: #e5e6e7; -} -/* FOOTER */ -.footer { - background: none repeat scroll 0 0 white; - border-top: 1px solid #e7eaec; - bottom: 0; - left: 0; - padding: 10px 20px; - position: absolute; - right: 0; -} -.footer.fixed_full { - position: fixed; - bottom: 0; - left: 0; - right: 0; - z-index: 1000; - padding: 10px 20px; - background: white; - border-top: 1px solid #e7eaec; -} -.footer.fixed { - position: fixed; - bottom: 0; - left: 0; - right: 0; - z-index: 1000; - padding: 10px 20px; - background: white; - border-top: 1px solid #e7eaec; - margin-left: 220px; -} -body.mini-navbar .footer.fixed, -body.body-small.mini-navbar .footer.fixed { - margin: 0 0 0 70px; -} -body.mini-navbar.canvas-menu .footer.fixed, -body.canvas-menu .footer.fixed { - margin: 0 !important; -} -body.fixed-sidebar.body-small.mini-navbar .footer.fixed { - margin: 0 0 0 220px; -} -body.body-small .footer.fixed { - margin-left: 0; -} -/* PANELS */ -.page-heading { - border-top: 0; - padding: 0 10px 20px 10px; -} -.panel-heading h1, -.panel-heading h2 { - margin-bottom: 5px; -} -/* TABLES */ -.table-bordered { - border: 1px solid #EBEBEB; -} -.table-bordered > thead > tr > th, -.table-bordered > thead > tr > td { - background-color: #F5F5F6; - border-bottom-width: 1px; -} -.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 #e7e7e7; -} -.table > thead > tr > th { - border-bottom: 1px solid #DDDDDD; - vertical-align: bottom; -} -.table > thead > tr > th, -.table > tbody > tr > th, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > tbody > tr > td, -.table > tfoot > tr > td { - border-top: 1px solid #e7eaec; - line-height: 1.42857; - padding: 8px; - vertical-align: top; -} -/* PANELS */ -.panel.blank-panel { - background: none; - margin: 0; -} -.blank-panel .panel-heading { - padding-bottom: 0; -} -.nav-tabs > li.active > a, -.nav-tabs > li.active > a:hover, -.nav-tabs > li.active > a:focus { - -moz-border-bottom-colors: none; - -moz-border-left-colors: none; - -moz-border-right-colors: none; - -moz-border-top-colors: none; - background: none; - border-color: #dddddd #dddddd rgba(0, 0, 0, 0); - border-bottom: #f3f3f4; - border-image: none; - border-style: solid; - border-width: 1px; - color: #555555; - cursor: default; -} -.nav.nav-tabs li { - background: none; - border: none; -} -.nav-tabs > li > a { - color: #A7B1C2; - font-weight: 600; - padding: 10px 20px 10px 25px; -} -.nav-tabs > li > a:hover, -.nav-tabs > li > a:focus { - background-color: #e6e6e6; - color: #676a6c; -} -.ui-tab .tab-content { - padding: 20px 0; -} -/* GLOBAL */ -.no-padding { - padding: 0 !important; -} -.no-borders { - border: none !important; -} -.no-margins { - margin: 0 !important; -} -.no-top-border { - border-top: 0 !important; -} -.ibox-content.text-box { - padding-bottom: 0; - padding-top: 15px; -} -.border-left-right { - border-left: 1px solid #e7eaec; - border-right: 1px solid #e7eaec; - border-top: none; - border-bottom: none; -} -.border-left { - border-left: 1px solid #e7eaec; - border-right: none; - border-top: none; - border-bottom: none; -} -.border-right { - border-left: none; - border-right: 1px solid #e7eaec; - border-top: none; - border-bottom: none; -} -.full-width { - width: 100% !important; -} -.link-block { - font-size: 12px; - padding: 10px; -} -.nav.navbar-top-links .link-block a { - font-size: 12px; -} -.link-block a { - font-size: 10px; - color: inherit; -} -body.mini-navbar .branding { - display: none; -} -img.circle-border { - border: 6px solid #FFFFFF; - border-radius: 50%; -} -.branding { - float: left; - color: #FFFFFF; - font-size: 18px; - font-weight: 600; - padding: 17px 20px; - text-align: center; - background-color: #007C82; -} -.login-panel { - margin-top: 25%; -} -.icons-box h3 { - margin-top: 10px; - margin-bottom: 10px; -} -.icons-box .infont a i { - font-size: 25px; - display: block; - color: #676a6c; -} -.icons-box .infont a { - color: #a6a8a9; -} -.icons-box .infont a { - padding: 10px; - margin: 1px; - display: block; -} -.ui-draggable .ibox-title { - cursor: move; -} -.breadcrumb { - background-color: #ffffff; - padding: 0; - margin-bottom: 0; -} -.breadcrumb > li a { - color: inherit; -} -.breadcrumb > .active { - color: inherit; -} -code { - background-color: #F9F2F4; - border-radius: 4px; - color: #ca4440; - font-size: 90%; - padding: 2px 4px; - white-space: nowrap; -} -.ibox { - clear: both; - margin-bottom: 25px; - margin-top: 0; - padding: 0; -} -.ibox.collapsed .ibox-content { - display: none; -} -.ibox.collapsed .fa.fa-chevron-up:before { - content: "\f078"; -} -.ibox.collapsed .fa.fa-chevron-down:before { - content: "\f077"; -} -.ibox:after, -.ibox:before { - display: table; -} -.ibox-title { - -moz-border-bottom-colors: none; - -moz-border-left-colors: none; - -moz-border-right-colors: none; - -moz-border-top-colors: none; - background-color: #ffffff; - border-color: #e7eaec; - border-image: none; - border-style: solid solid none; - border-width: 3px 0 0; - color: inherit; - margin-bottom: 0; - padding: 14px 15px 7px; - min-height: 48px; -} -.ibox-content { - background-color: #ffffff; - color: inherit; - padding: 15px 20px 20px 20px; - border-color: #e7eaec; - border-image: none; - border-style: solid solid none; - border-width: 1px 0; -} -.ibox-footer { - color: inherit; - border-top: 1px solid #e7eaec; - font-size: 90%; - background: #ffffff; - padding: 10px 15px; -} -table.table-mail tr td { - padding: 12px; -} -.table-mail .check-mail { - padding-left: 20px; -} -.table-mail .mail-date { - padding-right: 20px; -} -.star-mail, -.check-mail { - width: 40px; -} -.unread td a, -.unread td { - font-weight: 600; - color: inherit; -} -.read td a, -.read td { - font-weight: normal; - color: inherit; -} -.unread td { - background-color: #f9f8f8; -} -.ibox-content { - clear: both; -} -.ibox-heading { - background-color: #f3f6fb; - border-bottom: none; -} -.ibox-heading h3 { - font-weight: 200; - font-size: 24px; -} -.ibox-title h5 { - display: inline-block; - font-size: 14px; - margin: 0 0 7px; - padding: 0; - text-overflow: ellipsis; - float: left; -} -.ibox-title .label { - float: left; - margin-left: 4px; -} -.ibox-tools { - display: block; - float: none; - margin-top: 0; - position: relative; - padding: 0; - text-align: right; -} -.ibox-tools a { - cursor: pointer; - margin-left: 5px; - color: #c4c4c4; -} -.ibox-tools a.btn-primary { - color: #fff; -} -.ibox-tools .dropdown-menu > li > a { - padding: 4px 10px; - font-size: 12px; -} -.ibox .ibox-tools.open > .dropdown-menu { - left: auto; - right: 0; -} -/* BACKGROUNDS */ -.gray-bg { - background-color: #f3f3f4; -} -.white-bg { - background-color: #ffffff; -} -.navy-bg { - background-color: #007C82; - color: #ffffff; -} -.blue-bg { - background-color: #1c84c6; - color: #ffffff; -} -.lazur-bg { - background-color: #23c6c8; - color: #ffffff; -} -.yellow-bg { - background-color: #f8ac59; - color: #ffffff; -} -.red-bg { - background-color: #ed5565; - color: #ffffff; -} -.black-bg { - background-color: #262626; -} -.panel-primary { - border-color: #007C82; -} -.panel-primary > .panel-heading { - background-color: #007C82; - border-color: #007C82; -} -.panel-success { - border-color: #1c84c6; -} -.panel-success > .panel-heading { - background-color: #1c84c6; - border-color: #1c84c6; - color: #ffffff; -} -.panel-info { - border-color: #23c6c8; -} -.panel-info > .panel-heading { - background-color: #23c6c8; - border-color: #23c6c8; - color: #ffffff; -} -.panel-warning { - border-color: #f8ac59; -} -.panel-warning > .panel-heading { - background-color: #f8ac59; - border-color: #f8ac59; - color: #ffffff; -} -.panel-danger { - border-color: #ed5565; -} -.panel-danger > .panel-heading { - background-color: #ed5565; - border-color: #ed5565; - color: #ffffff; -} -.progress-bar { - background-color: #007C82; -} -.progress-small, -.progress-small .progress-bar { - height: 10px; -} -.progress-small, -.progress-mini { - margin-top: 5px; -} -.progress-mini, -.progress-mini .progress-bar { - height: 5px; - margin-bottom: 0; -} -.progress-bar-navy-light { - background-color: #3dc7ab; -} -.progress-bar-success { - background-color: #1c84c6; -} -.progress-bar-info { - background-color: #23c6c8; -} -.progress-bar-warning { - background-color: #f8ac59; -} -.progress-bar-danger { - background-color: #ed5565; -} -.panel-title { - font-size: inherit; -} -.jumbotron { - border-radius: 6px; - padding: 40px; -} -.jumbotron h1 { - margin-top: 0; -} -/* COLORS */ -.text-navy { - color: #007C82; -} -.text-primary { - color: inherit; -} -.text-success { - color: #1c84c6; -} -.text-info { - color: #23c6c8; -} -.text-warning { - color: #f8ac59; -} -.text-danger { - color: #ed5565; -} -.text-muted { - color: #888888; -} -.text-white { - color: #ffffff; -} -.simple_tag { - background-color: #f3f3f4; - border: 1px solid #e7eaec; - border-radius: 2px; - color: inherit; - font-size: 10px; - margin-right: 5px; - margin-top: 5px; - padding: 5px 12px; - display: inline-block; -} -.img-shadow { - -webkit-box-shadow: 0 0 3px 0 #919191; - -moz-box-shadow: 0 0 3px 0 #919191; - box-shadow: 0 0 3px 0 #919191; -} -/* For handle diferent bg color in AngularJS version */ -.dashboards\.dashboard_2 nav.navbar, -.dashboards\.dashboard_3 nav.navbar, -.mailbox\.inbox nav.navbar, -.mailbox\.email_view nav.navbar, -.mailbox\.email_compose nav.navbar, -.dashboards\.dashboard_4_1 nav.navbar, -.metrics nav.navbar, -.metrics\.index nav.navbar, -.dashboards\.dashboard_5 nav.navbar { - background: #fff; -} -/* For handle diferent bg color in MVC version */ -.Dashboard_2 .navbar.navbar-static-top, -.Dashboard_3 .navbar.navbar-static-top, -.Dashboard_4_1 .navbar.navbar-static-top, -.ComposeEmail .navbar.navbar-static-top, -.EmailView .navbar.navbar-static-top, -.Inbox .navbar.navbar-static-top, -.Metrics .navbar.navbar-static-top, -.Dashboard_5 .navbar.navbar-static-top { - background: #fff; -} -a.close-canvas-menu { - position: absolute; - top: 10px; - right: 15px; - z-index: 1011; - color: #a7b1c2; -} -a.close-canvas-menu:hover { - color: #fff; -} -.close-canvas-menu { - display: none; -} -.canvas-menu .close-canvas-menu { - display: block; -} -.light-navbar .navbar.navbar-static-top { - background-color: #ffffff; -} -/* FULL HEIGHT */ -.full-height { - height: 100%; -} -.fh-breadcrumb { - height: calc(100% - 196px); - margin: 0 -15px; - position: relative; -} -.fh-no-breadcrumb { - height: calc(100% - 99px); - margin: 0 -15px; - position: relative; -} -.fh-column { - background: #fff; - height: 100%; - width: 240px; - float: left; -} -.modal-backdrop { - z-index: 2040 !important; -} -.modal { - z-index: 2050 !important; -} -.spiner-example { - height: 200px; - padding-top: 70px; -} -/* MARGINS & PADDINGS */ -.p-xxs { - padding: 5px; -} -.p-xs { - padding: 10px; -} -.p-sm { - padding: 15px; -} -.p-m { - padding: 20px; -} -.p-md { - padding: 25px; -} -.p-lg { - padding: 30px; -} -.p-xl { - padding: 40px; -} -.p-w-xs { - padding: 0 10px; -} -.p-w-sm { - padding: 0 15px; -} -.p-w-m { - padding: 0 20px; -} -.p-w-md { - padding: 0 25px; -} -.p-w-lg { - padding: 0 30px; -} -.p-w-xl { - padding: 0 40px; -} -.m-xxs { - margin: 2px 4px; -} -.m-xs { - margin: 5px; -} -.m-sm { - margin: 10px; -} -.m { - margin: 15px; -} -.m-md { - margin: 20px; -} -.m-lg { - margin: 30px; -} -.m-xl { - margin: 50px; -} -.m-n { - margin: 0 !important; -} -.m-l-none { - margin-left: 0; -} -.m-l-xs { - margin-left: 5px; -} -.m-l-sm { - margin-left: 10px; -} -.m-l { - margin-left: 15px; -} -.m-l-md { - margin-left: 20px; -} -.m-l-lg { - margin-left: 30px; -} -.m-l-xl { - margin-left: 40px; -} -.m-l-n-xxs { - margin-left: -1px; -} -.m-l-n-xs { - margin-left: -5px; -} -.m-l-n-sm { - margin-left: -10px; -} -.m-l-n { - margin-left: -15px; -} -.m-l-n-md { - margin-left: -20px; -} -.m-l-n-lg { - margin-left: -30px; -} -.m-l-n-xl { - margin-left: -40px; -} -.m-t-none { - margin-top: 0; -} -.m-t-xxs { - margin-top: 1px; -} -.m-t-xs { - margin-top: 5px; -} -.m-t-sm { - margin-top: 10px; -} -.m-t { - margin-top: 15px; -} -.m-t-md { - margin-top: 20px; -} -.m-t-lg { - margin-top: 30px; -} -.m-t-xl { - margin-top: 40px; -} -.m-t-n-xxs { - margin-top: -1px; -} -.m-t-n-xs { - margin-top: -5px; -} -.m-t-n-sm { - margin-top: -10px; -} -.m-t-n { - margin-top: -15px; -} -.m-t-n-md { - margin-top: -20px; -} -.m-t-n-lg { - margin-top: -30px; -} -.m-t-n-xl { - margin-top: -40px; -} -.m-r-none { - margin-right: 0; -} -.m-r-xxs { - margin-right: 1px; -} -.m-r-xs { - margin-right: 5px; -} -.m-r-sm { - margin-right: 10px; -} -.m-r { - margin-right: 15px; -} -.m-r-md { - margin-right: 20px; -} -.m-r-lg { - margin-right: 30px; -} -.m-r-xl { - margin-right: 40px; -} -.m-r-n-xxs { - margin-right: -1px; -} -.m-r-n-xs { - margin-right: -5px; -} -.m-r-n-sm { - margin-right: -10px; -} -.m-r-n { - margin-right: -15px; -} -.m-r-n-md { - margin-right: -20px; -} -.m-r-n-lg { - margin-right: -30px; -} -.m-r-n-xl { - margin-right: -40px; -} -.m-b-none { - margin-bottom: 0; -} -.m-b-xxs { - margin-bottom: 1px; -} -.m-b-xs { - margin-bottom: 5px; -} -.m-b-sm { - margin-bottom: 10px; -} -.m-b { - margin-bottom: 15px; -} -.m-b-md { - margin-bottom: 20px; -} -.m-b-lg { - margin-bottom: 30px; -} -.m-b-xl { - margin-bottom: 40px; -} -.m-b-n-xxs { - margin-bottom: -1px; -} -.m-b-n-xs { - margin-bottom: -5px; -} -.m-b-n-sm { - margin-bottom: -10px; -} -.m-b-n { - margin-bottom: -15px; -} -.m-b-n-md { - margin-bottom: -20px; -} -.m-b-n-lg { - margin-bottom: -30px; -} -.m-b-n-xl { - margin-bottom: -40px; -} -.space-15 { - margin: 15px 0; -} -.space-20 { - margin: 20px 0; -} -.space-25 { - margin: 25px 0; -} -.space-30 { - margin: 30px 0; -} -.fullscreen-ibox-mode .animated { - animation: none; -} -body.fullscreen-ibox-mode { - overflow-y: hidden; -} -.ibox.fullscreen { - z-index: 2030; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - overflow: auto; - margin-bottom: 0; -} -.ibox.fullscreen .collapse-link { - display: none; -} -.ibox.fullscreen .ibox-content { - min-height: calc(100% - 48px); -} -body.modal-open { - padding-right: inherit !important; -} -body.modal-open .animated { - animation-fill-mode: initial; - z-index: inherit; -} -/* Show profile dropdown on fixed sidebar */ -body.mini-navbar.fixed-sidebar .profile-element, -.block { - display: block !important; -} -body.mini-navbar.fixed-sidebar .nav-header { - padding: 33px 25px; -} -body.mini-navbar.fixed-sidebar .logo-element { - display: none; -} -.fullscreen-video .animated { - animation: none; -} -/* SEARCH PAGE */ -.search-form { - margin-top: 10px; -} -.search-result h3 { - margin-bottom: 0; - color: #1E0FBE; -} -.search-result .search-link { - color: #006621; -} -.search-result p { - font-size: 12px; - margin-top: 5px; -} -/* CONTACTS */ -.contact-box { - background-color: #ffffff; - border: 1px solid #e7eaec; - padding: 20px; - margin-bottom: 20px; -} -.contact-box > a { - color: inherit; -} -.contact-box.center-version { - border: 1px solid #e7eaec; - padding: 0; -} -.contact-box.center-version > a { - display: block; - background-color: #ffffff; - padding: 20px; - text-align: center; -} -.contact-box.center-version > a img { - width: 80px; - height: 80px; - margin-top: 10px; - margin-bottom: 10px; -} -.contact-box.center-version address { - margin-bottom: 0; -} -.contact-box .contact-box-footer { - text-align: center; - background-color: #ffffff; - border-top: 1px solid #e7eaec; - padding: 15px 20px; -} -/* INVOICE */ -.invoice-table tbody > tr > td:last-child, -.invoice-table tbody > tr > td:nth-child(4), -.invoice-table tbody > tr > td:nth-child(3), -.invoice-table tbody > tr > td:nth-child(2) { - text-align: right; -} -.invoice-table thead > tr > th:last-child, -.invoice-table thead > tr > th:nth-child(4), -.invoice-table thead > tr > th:nth-child(3), -.invoice-table thead > tr > th:nth-child(2) { - text-align: right; -} -.invoice-total > tbody > tr > td:first-child { - text-align: right; -} -.invoice-total > tbody > tr > td { - border: 0 none; -} -.invoice-total > tbody > tr > td:last-child { - border-bottom: 1px solid #DDDDDD; - text-align: right; - width: 15%; -} -/* ERROR & LOGIN & LOCKSCREEN*/ -.middle-box { - max-width: 400px; - z-index: 100; - margin: 0 auto; - padding-top: 40px; -} -.lockscreen.middle-box { - width: 200px; - padding-top: 110px; -} -.loginscreen.middle-box { - width: 300px; -} -.loginColumns { - max-width: 800px; - margin: 0 auto; - padding: 100px 20px 20px 20px; -} -.passwordBox { - max-width: 460px; - margin: 0 auto; - padding: 100px 20px 20px 20px; -} -.logo-name { - color: #e6e6e6; - font-size: 1800px; - font-weight: 800; - letter-spacing: -10px; - margin-bottom: 0; - margin-left:-10px; -} -.middle-box h1 { - font-size: 170px; -} -.wrapper .middle-box { - margin-top: 140px; -} -.lock-word { - z-index: 10; - position: absolute; - top: 110px; - left: 50%; - margin-left: -470px; -} -.lock-word span { - font-size: 100px; - font-weight: 600; - color: #e9e9e9; - display: inline-block; -} -.lock-word .first-word { - margin-right: 160px; -} -/* DASBOARD */ -.dashboard-header { - border-top: 0; - padding: 20px 20px 20px 20px; -} -.dashboard-header h2 { - margin-top: 10px; - font-size: 26px; -} -.fist-item { - border-top: none !important; -} -.statistic-box { - margin-top: 40px; -} -.dashboard-header .list-group-item span.label { - margin-right: 10px; -} -.list-group.clear-list .list-group-item { - border-top: 1px solid #e7eaec; - border-bottom: 0; - border-right: 0; - border-left: 0; - padding: 10px 0; -} -ul.clear-list:first-child { - border-top: none !important; -} -/* Intimeline */ -.timeline-item .date i { - position: absolute; - top: 0; - right: 0; - padding: 5px; - width: 30px; - text-align: center; - border-top: 1px solid #e7eaec; - border-bottom: 1px solid #e7eaec; - border-left: 1px solid #e7eaec; - background: #f8f8f8; -} -.timeline-item .date { - text-align: right; - width: 110px; - position: relative; - padding-top: 30px; -} -.timeline-item .content { - border-left: 1px solid #e7eaec; - border-top: 1px solid #e7eaec; - padding-top: 10px; - min-height: 100px; -} -.timeline-item .content:hover { - background: #f6f6f6; -} -/* PIN BOARD */ -ul.notes li, -ul.tag-list li { - list-style: none; -} -ul.notes li h4 { - margin-top: 20px; - font-size: 16px; -} -ul.notes li div { - text-decoration: none; - color: #000; - background: #ffc; - display: block; - height: 140px; - width: 140px; - padding: 1em; - position: relative; -} -ul.notes li div small { - position: absolute; - top: 5px; - right: 5px; - font-size: 10px; -} -ul.notes li div a { - position: absolute; - right: 10px; - bottom: 10px; - color: inherit; -} -ul.notes li { - margin: 10px 40px 50px 0; - float: left; -} -ul.notes li div p { - font-size: 12px; -} -ul.notes li div { - text-decoration: none; - color: #000; - background: #ffc; - display: block; - height: 140px; - width: 140px; - padding: 1em; - /* Firefox */ - -moz-box-shadow: 5px 5px 2px #212121; - /* Safari+Chrome */ - -webkit-box-shadow: 5px 5px 2px rgba(33, 33, 33, 0.7); - /* Opera */ - box-shadow: 5px 5px 2px rgba(33, 33, 33, 0.7); -} -ul.notes li div { - -webkit-transform: rotate(-6deg); - -o-transform: rotate(-6deg); - -moz-transform: rotate(-6deg); -} -ul.notes li:nth-child(even) div { - -o-transform: rotate(4deg); - -webkit-transform: rotate(4deg); - -moz-transform: rotate(4deg); - position: relative; - top: 5px; -} -ul.notes li:nth-child(3n) div { - -o-transform: rotate(-3deg); - -webkit-transform: rotate(-3deg); - -moz-transform: rotate(-3deg); - position: relative; - top: -5px; -} -ul.notes li:nth-child(5n) div { - -o-transform: rotate(5deg); - -webkit-transform: rotate(5deg); - -moz-transform: rotate(5deg); - position: relative; - top: -10px; -} -ul.notes li div:hover, -ul.notes li div:focus { - -webkit-transform: scale(1.1); - -moz-transform: scale(1.1); - -o-transform: scale(1.1); - position: relative; - z-index: 5; -} -ul.notes li div { - text-decoration: none; - color: #000; - background: #ffc; - display: block; - height: 210px; - width: 210px; - padding: 1em; - -moz-box-shadow: 5px 5px 7px #212121; - -webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, 0.7); - box-shadow: 5px 5px 7px rgba(33, 33, 33, 0.7); - -moz-transition: -moz-transform 0.15s linear; - -o-transition: -o-transform 0.15s linear; - -webkit-transition: -webkit-transform 0.15s linear; -} -/* FILE MANAGER */ -.file-box { - float: left; - width: 220px; -} -.file-manager h5 { - text-transform: uppercase; -} -.file-manager { - list-style: none outside none; - margin: 0; - padding: 0; -} -.folder-list li a { - color: #666666; - display: block; - padding: 5px 0; -} -.folder-list li { - border-bottom: 1px solid #e7eaec; - display: block; -} -.folder-list li i { - margin-right: 8px; - color: #3d4d5d; -} -.category-list li a { - color: #666666; - display: block; - padding: 5px 0; -} -.category-list li { - display: block; -} -.category-list li i { - margin-right: 8px; - color: #3d4d5d; -} -.category-list li a .text-navy { - color: #007C82; -} -.category-list li a .text-primary { - color: #1c84c6; -} -.category-list li a .text-info { - color: #23c6c8; -} -.category-list li a .text-danger { - color: #EF5352; -} -.category-list li a .text-warning { - color: #F8AC59; -} -.file-manager h5.tag-title { - margin-top: 20px; -} -.tag-list li { - float: left; -} -.tag-list li a { - font-size: 10px; - background-color: #f3f3f4; - padding: 5px 12px; - color: inherit; - border-radius: 2px; - border: 1px solid #e7eaec; - margin-right: 5px; - margin-top: 5px; - display: block; -} -.file { - border: 1px solid #e7eaec; - padding: 0; - background-color: #ffffff; - position: relative; - margin-bottom: 20px; - margin-right: 20px; -} -.file-manager .hr-line-dashed { - margin: 15px 0; -} -.file .icon, -.file .image { - height: 100px; - overflow: hidden; -} -.file .icon { - padding: 15px 10px; - text-align: center; -} -.file-control { - color: inherit; - font-size: 11px; - margin-right: 10px; -} -.file-control.active { - text-decoration: underline; -} -.file .icon i { - font-size: 70px; - color: #dadada; -} -.file .file-name { - padding: 10px; - background-color: #f8f8f8; - border-top: 1px solid #e7eaec; -} -.file-name small { - color: #676a6c; -} -.corner { - position: absolute; - display: inline-block; - width: 0; - height: 0; - line-height: 0; - border: 0.6em solid transparent; - border-right: 0.6em solid #f1f1f1; - border-bottom: 0.6em solid #f1f1f1; - right: 0em; - bottom: 0em; -} -a.compose-mail { - padding: 8px 10px; -} -.mail-search { - max-width: 300px; -} -/* PROFILE */ -.profile-content { - border-top: none !important; -} -.profile-stats { - margin-right: 10px; -} -.profile-image { - width: 120px; - float: left; -} -.profile-image img { - width: 96px; - height: 96px; -} -.profile-info { - margin-left: 120px; -} -.feed-activity-list .feed-element { - border-bottom: 1px solid #e7eaec; -} -.feed-element:first-child { - margin-top: 0; -} -.feed-element { - padding-bottom: 15px; -} -.feed-element, -.feed-element .media { - margin-top: 15px; -} -.feed-element, -.media-body { - overflow: hidden; -} -.feed-element > .pull-left { - margin-right: 10px; -} -.feed-element img.img-circle, -.dropdown-messages-box img.img-circle { - width: 38px; - height: 38px; -} -.feed-element .well { - border: 1px solid #e7eaec; - box-shadow: none; - margin-top: 10px; - margin-bottom: 5px; - padding: 10px 20px; - font-size: 11px; - line-height: 16px; -} -.feed-element .actions { - margin-top: 10px; -} -.feed-element .photos { - margin: 10px 0; -} -.feed-photo { - max-height: 180px; - border-radius: 4px; - overflow: hidden; - margin-right: 10px; - margin-bottom: 10px; -} -.file-list li { - padding: 5px 10px; - font-size: 11px; - border-radius: 2px; - border: 1px solid #e7eaec; - margin-bottom: 5px; -} -.file-list li a { - color: inherit; -} -.file-list li a:hover { - color: #007C82; -} -.user-friends img { - width: 42px; - height: 42px; - margin-bottom: 5px; - margin-right: 5px; -} -/* MAILBOX */ -.mail-box { - background-color: #ffffff; - border: 1px solid #e7eaec; - border-top: 0; - padding: 0; - margin-bottom: 20px; -} -.mail-box-header { - background-color: #ffffff; - border: 1px solid #e7eaec; - border-bottom: 0; - padding: 30px 20px 20px 20px; -} -.mail-box-header h2 { - margin-top: 0; -} -.mailbox-content .tag-list li a { - background: #ffffff; -} -.mail-body { - border-top: 1px solid #e7eaec; - padding: 20px; -} -.mail-text { - border-top: 1px solid #e7eaec; -} -.mail-text .note-toolbar { - padding: 10px 15px; -} -.mail-body .form-group { - margin-bottom: 5px; -} -.mail-text .note-editor .note-toolbar { - background-color: #F9F8F8; -} -.mail-attachment { - border-top: 1px solid #e7eaec; - padding: 20px; - font-size: 12px; -} -.mailbox-content { - background: none; - border: none; - padding: 10px; -} -.mail-ontact { - width: 23%; -} -/* PROJECTS */ -.project-people, -.project-actions { - text-align: right; - vertical-align: middle; -} -dd.project-people { - text-align: left; - margin-top: 5px; -} -.project-people img { - width: 32px; - height: 32px; -} -.project-title a { - font-size: 14px; - color: #676a6c; - font-weight: 600; -} -.project-list table tr td { - border-top: none; - border-bottom: 1px solid #e7eaec; - padding: 15px 10px; - vertical-align: middle; -} -.project-manager .tag-list li a { - font-size: 10px; - background-color: white; - padding: 5px 12px; - color: inherit; - border-radius: 2px; - border: 1px solid #e7eaec; - margin-right: 5px; - margin-top: 5px; - display: block; -} -.project-files li a { - font-size: 11px; - color: #676a6c; - margin-left: 10px; - line-height: 22px; -} -/* FAQ */ -.faq-item { - padding: 20px; - margin-bottom: 2px; - background: #fff; -} -.faq-question { - font-size: 18px; - font-weight: 600; - color: #007C82; - display: block; -} -.faq-question:hover { - color: #179d82; -} -.faq-answer { - margin-top: 10px; - background: #f3f3f4; - border: 1px solid #e7eaec; - border-radius: 3px; - padding: 15px; -} -.faq-item .tag-item { - background: #f3f3f4; - padding: 2px 6px; - font-size: 10px; - text-transform: uppercase; -} -/* Chat view */ -.message-input { - height: 90px !important; -} -.chat-avatar { - white: 36px; - height: 36px; - float: left; - margin-right: 10px; -} -.chat-user-name { - padding: 10px; -} -.chat-user { - padding: 8px 10px; - border-bottom: 1px solid #e7eaec; -} -.chat-user a { - color: inherit; -} -.chat-view { - z-index: 20012; -} -.chat-users, -.chat-statistic { - margin-left: -30px; -} -@media (max-width: 992px) { - .chat-users, - .chat-statistic { - margin-left: 0; - } -} -.chat-view .ibox-content { - padding: 0; -} -.chat-message { - padding: 10px 20px; -} -.message-avatar { - height: 48px; - width: 48px; - border: 1px solid #e7eaec; - border-radius: 4px; - margin-top: 1px; -} -.chat-discussion .chat-message.left .message-avatar { - float: left; - margin-right: 10px; -} -.chat-discussion .chat-message.right .message-avatar { - float: right; - margin-left: 10px; -} -.message { - background-color: #fff; - border: 1px solid #e7eaec; - text-align: left; - display: block; - padding: 10px 20px; - position: relative; - border-radius: 4px; -} -.chat-discussion .chat-message.left .message-date { - float: right; -} -.chat-discussion .chat-message.right .message-date { - float: left; -} -.chat-discussion .chat-message.left .message { - text-align: left; - margin-left: 55px; -} -.chat-discussion .chat-message.right .message { - text-align: right; - margin-right: 55px; -} -.message-date { - font-size: 10px; - color: #888888; -} -.message-content { - display: block; -} -.chat-discussion { - background: #eee; - padding: 15px; - height: 400px; - overflow-y: auto; -} -.chat-users { - overflow-y: auto; - height: 400px; -} -.chat-message-form .form-group { - margin-bottom: 0; -} -/* jsTree */ -.jstree-open > .jstree-anchor > .fa-folder:before { - content: "\f07c"; -} -.jstree-default .jstree-icon.none { - width: 0; -} -/* CLIENTS */ -.clients-list { - margin-top: 20px; -} -.clients-list .tab-pane { - position: relative; - height: 600px; -} -.client-detail { - position: relative; - height: 620px; -} -.clients-list table tr td { - height: 46px; - vertical-align: middle; - border: none; -} -.client-link { - font-weight: 600; - color: inherit; -} -.client-link:hover { - color: inherit; -} -.client-avatar { - width: 42px; -} -.client-avatar img { - width: 28px; - height: 28px; - border-radius: 50%; -} -.contact-type { - width: 20px; - color: #c1c3c4; -} -.client-status { - text-align: left; -} -.client-detail .vertical-timeline-content p { - margin: 0; -} -.client-detail .vertical-timeline-icon.gray-bg { - color: #a7aaab; -} -.clients-list .nav-tabs > li.active > a, -.clients-list .nav-tabs > li.active > a:hover, -.clients-list .nav-tabs > li.active > a:focus { - border-bottom: 1px solid #fff; -} -/* BLOG ARTICLE */ -.blog h2 { - font-weight: 700; -} -.blog h5 { - margin: 0 0 5px 0; -} -.blog .btn { - margin: 0 0 5px 0; -} -.article h1 { - font-size: 48px; - font-weight: 700; - color: #2F4050; -} -.article p { - font-size: 15px; - line-height: 26px; -} -.article-title { - text-align: center; - margin: 40px 0 100px 0; -} -.article .ibox-content { - padding: 40px; -} -/* ISSUE TRACKER */ -.issue-tracker .btn-link { - color: #007C82; -} -table.issue-tracker tbody tr td { - vertical-align: middle; - height: 50px; -} -.issue-info { - width: 50%; -} -.issue-info a { - font-weight: 600; - color: #676a6c; -} -.issue-info small { - display: block; -} -/* TEAMS */ -.team-members { - margin: 10px 0; -} -.team-members img.img-circle { - width: 42px; - height: 42px; - margin-bottom: 5px; -} -/* AGILE BOARD */ -.sortable-list { - padding: 10px 0; -} -.agile-list { - list-style: none; - margin: 0; -} -.agile-list li { - background: #FAFAFB; - border: 1px solid #e7eaec; - margin: 0 0 10px 0; - padding: 10px; - border-radius: 2px; -} -.agile-list li:hover { - cursor: pointer; - background: #fff; -} -.agile-list li.warning-element { - border-left: 3px solid #f8ac59; -} -.agile-list li.danger-element { - border-left: 3px solid #ed5565; -} -.agile-list li.info-element { - border-left: 3px solid #1c84c6; -} -.agile-list li.success-element { - border-left: 3px solid #007C82; -} -.agile-detail { - margin-top: 5px; - font-size: 12px; -} -/* DIFF */ -ins { - background-color: #c6ffc6; - text-decoration: none; -} -del { - background-color: #ffc6c6; -} -/* E-commerce */ -.product-box { - padding: 0; - border: 1px solid #e7eaec; -} -.product-box:hover, -.product-box.active { - border: 1px solid transparent; - -webkit-box-shadow: 0 3px 7px 0 #a8a8a8; - -moz-box-shadow: 0 3px 7px 0 #a8a8a8; - box-shadow: 0 3px 7px 0 #a8a8a8; -} -.product-imitation { - text-align: center; - padding: 0px 0; - background-color: #f8f8f9; - color: #bebec3; - font-weight: 600; - width:100%; height:200px; -} -.product-imitation img { - width:100%; height:200px; -} -.cart-product-imitation { - text-align: center; - padding-top: 30px; - height: 80px; - width: 80px; - background-color: #f8f8f9; -} -.product-imitation.xl { - padding: 120px 0; -} -.product-desc { - padding: 20px; - position: relative; -} -.ecommerce .tag-list { - padding: 0; -} -.ecommerce .fa-star { - color: #d1dade; -} -.ecommerce .fa-star.active { - color: #f8ac59; -} -.ecommerce .note-editor { - border: 1px solid #e7eaec; -} -table.shoping-cart-table { - margin-bottom: 0; -} -table.shoping-cart-table tr td { - border: none; - text-align: right; -} -table.shoping-cart-table tr td.desc, -table.shoping-cart-table tr td:first-child { - text-align: left; -} -table.shoping-cart-table tr td:last-child { - width: 80px; -} -.product-name { - font-size: 16px; - font-weight: 600; - color: #676a6c; - display: block; - margin: 2px 0 5px 0; -} -.product-name:hover, -.product-name:focus { - color: #007C82; -} -.product-price { - font-size: 14px; - font-weight: 600; - color: #ffffff; - background-color: #007C82; - padding: 6px 12px; - position: absolute; - top: -32px; - right: 0; -} -.product-detail .ibox-content { - padding: 30px 30px 50px 30px; -} -.image-imitation { - background-color: #f8f8f9; - text-align: center; - padding: 200px 0; -} -.product-main-price small { - font-size: 10px; -} -.product-images { - margin: 0 20px; -} -/* Social feed */ -.social-feed-separated .social-feed-box { - margin-left: 62px; -} -.social-feed-separated .social-avatar { - float: left; - padding: 0; -} -.social-feed-separated .social-avatar img { - width: 52px; - height: 52px; - border: 1px solid #e7eaec; -} -.social-feed-separated .social-feed-box .social-avatar { - padding: 15px 15px 0 15px; - float: none; -} -.social-feed-box { - /*padding: 15px;*/ - border: 1px solid #e7eaec; - background: #fff; - margin-bottom: 15px; -} -.article .social-feed-box { - margin-bottom: 0; - border-bottom: none; -} -.article .social-feed-box:last-child { - margin-bottom: 0; - border-bottom: 1px solid #e7eaec; -} -.article .social-feed-box p { - font-size: 13px; - line-height: 18px; -} -.social-action { - margin: 15px; -} -.social-avatar { - padding: 15px 15px 0 15px; -} -.social-comment .social-comment { - margin-left: 45px; -} -.social-avatar img { - height: 40px; - width: 40px; - margin-right: 10px; -} -.social-avatar .media-body a { - font-size: 14px; - display: block; -} -.social-body { - padding: 15px; -} -.social-body img { - margin-bottom: 10px; -} -.social-footer { - border-top: 1px solid #e7eaec; - padding: 10px 15px; - background: #f9f9f9; -} -.social-footer .social-comment img { - width: 32px; - margin-right: 10px; -} -.social-comment:first-child { - margin-top: 0; -} -.social-comment { - margin-top: 15px; -} -.social-comment textarea { - font-size: 12px; -} -/* Vote list */ -.vote-item { - padding: 20px 25px; - background: #ffffff; - border-top: 1px solid #e7eaec; -} -.vote-item:last-child { - border-bottom: 1px solid #e7eaec; -} -.vote-item:hover { - background: #fbfbfb; -} -.vote-actions { - float: left; - width: 30px; - margin-right: 15px; - text-align: center; -} -.vote-actions a { - color: #007C82; - font-weight: 600; -} -.vote-actions { - font-weight: 600; -} -.vote-title { - display: block; - color: inherit; - font-size: 18px; - font-weight: 600; - margin-top: 5px; - margin-bottom: 2px; -} -.vote-title:hover, -.vote-title:focus { - color: inherit; -} -.vote-info, -.vote-title { - margin-left: 45px; -} -.vote-info, -.vote-info a { - color: #b4b6b8; - font-size: 12px; -} -.vote-info a { - margin-right: 10px; -} -.vote-info a:hover { - color: #007C82; -} -.vote-icon { - text-align: right; - font-size: 38px; - display: block; - color: #e8e9ea; -} -.vote-icon.active { - color: #007C82; -} -body.body-small .vote-icon { - display: none; -} -.lightBoxGallery { - text-align: center; -} -.lightBoxGallery img { - margin: 5px; -} -#small-chat { - position: fixed; - bottom: 20px; - right: 20px; - z-index: 100; -} -#small-chat .badge { - position: absolute; - top: -3px; - right: -4px; -} -.open-small-chat { - height: 38px; - width: 38px; - display: block; - background: #007C82; - padding: 9px 8px; - text-align: center; - color: #fff; - border-radius: 50%; -} -.open-small-chat:hover { - color: white; - background: #007C82; -} -.small-chat-box { - display: none; - position: fixed; - bottom: 20px; - right: 75px; - background: #fff; - border: 1px solid #e7eaec; - width: 230px; - height: 320px; - border-radius: 4px; -} -.small-chat-box.ng-small-chat { - display: block; -} -.body-small .small-chat-box { - bottom: 70px; - right: 20px; -} -.small-chat-box.active { - display: block; -} -.small-chat-box .heading { - background: #2f4050; - padding: 8px 15px; - font-weight: bold; - color: #fff; -} -.small-chat-box .chat-date { - opacity: 0.6; - font-size: 10px; - font-weight: normal; -} -.small-chat-box .content { - padding: 15px 15px; -} -.small-chat-box .content .author-name { - font-weight: bold; - margin-bottom: 3px; - font-size: 11px; -} -.small-chat-box .content > div { - padding-bottom: 20px; -} -.small-chat-box .content .chat-message { - padding: 5px 10px; - border-radius: 6px; - font-size: 11px; - line-height: 14px; - max-width: 80%; - background: #f3f3f4; - margin-bottom: 10px; -} -.small-chat-box .content .chat-message.active { - background: #007C82; - color: #fff; -} -.small-chat-box .content .left { - text-align: left; - clear: both; -} -.small-chat-box .content .left .chat-message { - float: left; -} -.small-chat-box .content .right { - text-align: right; - clear: both; -} -.small-chat-box .content .right .chat-message { - float: right; -} -.small-chat-box .form-chat { - padding: 10px 10px; -} -/* - * metismenu - v2.0.2 - * A jQuery menu plugin - * https://github.com/onokumus/metisMenu - * - * Made by Osman Nuri Okumus - * Under MIT License - */ -.metismenu .plus-minus, -.metismenu .plus-times { - float: right; -} -.metismenu .arrow { - float: right; - line-height: 1.42857; -} -.metismenu .glyphicon.arrow:before { - content: "\e079"; -} -.metismenu .active > a > .glyphicon.arrow:before { - content: "\e114"; -} -.metismenu .fa.arrow:before { - content: "\f104"; -} -.metismenu .active > a > .fa.arrow:before { - content: "\f107"; -} -.metismenu .ion.arrow:before { - content: "\f3d2"; -} -.metismenu .active > a > .ion.arrow:before { - content: "\f3d0"; -} -.metismenu .fa.plus-minus:before, -.metismenu .fa.plus-times:before { - content: "\f067"; -} -.metismenu .active > a > .fa.plus-times { - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} -.metismenu .active > a > .fa.plus-minus:before { - content: "\f068"; -} -.metismenu .collapse { - display: none; -} -.metismenu .collapse.in { - display: block; -} -.metismenu .collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-timing-function: ease; - transition-timing-function: ease; - -webkit-transition-duration: .35s; - transition-duration: .35s; - -webkit-transition-property: height, visibility; - transition-property: height, visibility; -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-rotating-plane"></div> - * - */ -.sk-spinner-rotating-plane.sk-spinner { - width: 30px; - height: 30px; - background-color: #007C82; - margin: 0 auto; - -webkit-animation: sk-rotatePlane 1.2s infinite ease-in-out; - animation: sk-rotatePlane 1.2s infinite ease-in-out; -} -@-webkit-keyframes sk-rotatePlane { - 0% { - -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); - transform: perspective(120px) rotateX(0deg) rotateY(0deg); - } - 50% { - -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - } - 100% { - -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - } -} -@keyframes sk-rotatePlane { - 0% { - -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); - transform: perspective(120px) rotateX(0deg) rotateY(0deg); - } - 50% { - -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); - } - 100% { - -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-double-bounce"> - * <div class="sk-double-bounce1"></div> - * <div class="sk-double-bounce2"></div> - * </div> - * - */ -.sk-spinner-double-bounce.sk-spinner { - width: 40px; - height: 40px; - position: relative; - margin: 0 auto; -} -.sk-spinner-double-bounce .sk-double-bounce1, -.sk-spinner-double-bounce .sk-double-bounce2 { - width: 100%; - height: 100%; - border-radius: 50%; - background-color: #007C82; - opacity: 0.6; - position: absolute; - top: 0; - left: 0; - -webkit-animation: sk-doubleBounce 2s infinite ease-in-out; - animation: sk-doubleBounce 2s infinite ease-in-out; -} -.sk-spinner-double-bounce .sk-double-bounce2 { - -webkit-animation-delay: -1s; - animation-delay: -1s; -} -@-webkit-keyframes sk-doubleBounce { - 0%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -@keyframes sk-doubleBounce { - 0%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-wave"> - * <div class="sk-rect1"></div> - * <div class="sk-rect2"></div> - * <div class="sk-rect3"></div> - * <div class="sk-rect4"></div> - * <div class="sk-rect5"></div> - * </div> - * - */ -.sk-spinner-wave.sk-spinner { - margin: 0 auto; - width: 50px; - height: 30px; - text-align: center; - font-size: 10px; -} -.sk-spinner-wave div { - background-color: #007C82; - height: 100%; - width: 6px; - display: inline-block; - -webkit-animation: sk-waveStretchDelay 1.2s infinite ease-in-out; - animation: sk-waveStretchDelay 1.2s infinite ease-in-out; -} -.sk-spinner-wave .sk-rect2 { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} -.sk-spinner-wave .sk-rect3 { - -webkit-animation-delay: -1s; - animation-delay: -1s; -} -.sk-spinner-wave .sk-rect4 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} -.sk-spinner-wave .sk-rect5 { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} -@-webkit-keyframes sk-waveStretchDelay { - 0%, - 40%, - 100% { - -webkit-transform: scaleY(0.4); - transform: scaleY(0.4); - } - 20% { - -webkit-transform: scaleY(1); - transform: scaleY(1); - } -} -@keyframes sk-waveStretchDelay { - 0%, - 40%, - 100% { - -webkit-transform: scaleY(0.4); - transform: scaleY(0.4); - } - 20% { - -webkit-transform: scaleY(1); - transform: scaleY(1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-wandering-cubes"> - * <div class="sk-cube1"></div> - * <div class="sk-cube2"></div> - * </div> - * - */ -.sk-spinner-wandering-cubes.sk-spinner { - margin: 0 auto; - width: 32px; - height: 32px; - position: relative; -} -.sk-spinner-wandering-cubes .sk-cube1, -.sk-spinner-wandering-cubes .sk-cube2 { - background-color: #007C82; - width: 10px; - height: 10px; - position: absolute; - top: 0; - left: 0; - -webkit-animation: sk-wanderingCubeMove 1.8s infinite ease-in-out; - animation: sk-wanderingCubeMove 1.8s infinite ease-in-out; -} -.sk-spinner-wandering-cubes .sk-cube2 { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} -@-webkit-keyframes sk-wanderingCubeMove { - 25% { - -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); - transform: translateX(42px) rotate(-90deg) scale(0.5); - } - 50% { - /* Hack to make FF rotate in the right direction */ - -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); - transform: translateX(42px) translateY(42px) rotate(-179deg); - } - 50.1% { - -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); - transform: translateX(42px) translateY(42px) rotate(-180deg); - } - 75% { - -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - } - 100% { - -webkit-transform: rotate(-360deg); - transform: rotate(-360deg); - } -} -@keyframes sk-wanderingCubeMove { - 25% { - -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); - transform: translateX(42px) rotate(-90deg) scale(0.5); - } - 50% { - /* Hack to make FF rotate in the right direction */ - -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); - transform: translateX(42px) translateY(42px) rotate(-179deg); - } - 50.1% { - -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); - transform: translateX(42px) translateY(42px) rotate(-180deg); - } - 75% { - -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); - } - 100% { - -webkit-transform: rotate(-360deg); - transform: rotate(-360deg); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-pulse"></div> - * - */ -.sk-spinner-pulse.sk-spinner { - width: 40px; - height: 40px; - margin: 0 auto; - background-color: #007C82; - border-radius: 100%; - -webkit-animation: sk-pulseScaleOut 1s infinite ease-in-out; - animation: sk-pulseScaleOut 1s infinite ease-in-out; -} -@-webkit-keyframes sk-pulseScaleOut { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 0; - } -} -@keyframes sk-pulseScaleOut { - 0% { - -webkit-transform: scale(0); - transform: scale(0); - } - 100% { - -webkit-transform: scale(1); - transform: scale(1); - opacity: 0; - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-chasing-dots"> - * <div class="sk-dot1"></div> - * <div class="sk-dot2"></div> - * </div> - * - */ -.sk-spinner-chasing-dots.sk-spinner { - margin: 0 auto; - width: 40px; - height: 40px; - position: relative; - text-align: center; - -webkit-animation: sk-chasingDotsRotate 2s infinite linear; - animation: sk-chasingDotsRotate 2s infinite linear; -} -.sk-spinner-chasing-dots .sk-dot1, -.sk-spinner-chasing-dots .sk-dot2 { - width: 60%; - height: 60%; - display: inline-block; - position: absolute; - top: 0; - background-color: #007C82; - border-radius: 100%; - -webkit-animation: sk-chasingDotsBounce 2s infinite ease-in-out; - animation: sk-chasingDotsBounce 2s infinite ease-in-out; -} -.sk-spinner-chasing-dots .sk-dot2 { - top: auto; - bottom: 0; - -webkit-animation-delay: -1s; - animation-delay: -1s; -} -@-webkit-keyframes sk-chasingDotsRotate { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@keyframes sk-chasingDotsRotate { - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@-webkit-keyframes sk-chasingDotsBounce { - 0%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -@keyframes sk-chasingDotsBounce { - 0%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 50% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-three-bounce"> - * <div class="sk-bounce1"></div> - * <div class="sk-bounce2"></div> - * <div class="sk-bounce3"></div> - * </div> - * - */ -.sk-spinner-three-bounce.sk-spinner { - margin: 0 auto; - width: 70px; - text-align: center; -} -.sk-spinner-three-bounce div { - width: 18px; - height: 18px; - background-color: #007C82; - border-radius: 100%; - display: inline-block; - -webkit-animation: sk-threeBounceDelay 1.4s infinite ease-in-out; - animation: sk-threeBounceDelay 1.4s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} -.sk-spinner-three-bounce .sk-bounce1 { - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; -} -.sk-spinner-three-bounce .sk-bounce2 { - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; -} -@-webkit-keyframes sk-threeBounceDelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 40% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -@keyframes sk-threeBounceDelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 40% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-circle"> - * <div class="sk-circle1 sk-circle"></div> - * <div class="sk-circle2 sk-circle"></div> - * <div class="sk-circle3 sk-circle"></div> - * <div class="sk-circle4 sk-circle"></div> - * <div class="sk-circle5 sk-circle"></div> - * <div class="sk-circle6 sk-circle"></div> - * <div class="sk-circle7 sk-circle"></div> - * <div class="sk-circle8 sk-circle"></div> - * <div class="sk-circle9 sk-circle"></div> - * <div class="sk-circle10 sk-circle"></div> - * <div class="sk-circle11 sk-circle"></div> - * <div class="sk-circle12 sk-circle"></div> - * </div> - * - */ -.sk-spinner-circle.sk-spinner { - margin: 0 auto; - width: 22px; - height: 22px; - position: relative; -} -.sk-spinner-circle .sk-circle { - width: 100%; - height: 100%; - position: absolute; - left: 0; - top: 0; -} -.sk-spinner-circle .sk-circle:before { - content: ''; - display: block; - margin: 0 auto; - width: 20%; - height: 20%; - background-color: #007C82; - border-radius: 100%; - -webkit-animation: sk-circleBounceDelay 1.2s infinite ease-in-out; - animation: sk-circleBounceDelay 1.2s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} -.sk-spinner-circle .sk-circle2 { - -webkit-transform: rotate(30deg); - -ms-transform: rotate(30deg); - transform: rotate(30deg); -} -.sk-spinner-circle .sk-circle3 { - -webkit-transform: rotate(60deg); - -ms-transform: rotate(60deg); - transform: rotate(60deg); -} -.sk-spinner-circle .sk-circle4 { - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.sk-spinner-circle .sk-circle5 { - -webkit-transform: rotate(120deg); - -ms-transform: rotate(120deg); - transform: rotate(120deg); -} -.sk-spinner-circle .sk-circle6 { - -webkit-transform: rotate(150deg); - -ms-transform: rotate(150deg); - transform: rotate(150deg); -} -.sk-spinner-circle .sk-circle7 { - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.sk-spinner-circle .sk-circle8 { - -webkit-transform: rotate(210deg); - -ms-transform: rotate(210deg); - transform: rotate(210deg); -} -.sk-spinner-circle .sk-circle9 { - -webkit-transform: rotate(240deg); - -ms-transform: rotate(240deg); - transform: rotate(240deg); -} -.sk-spinner-circle .sk-circle10 { - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} -.sk-spinner-circle .sk-circle11 { - -webkit-transform: rotate(300deg); - -ms-transform: rotate(300deg); - transform: rotate(300deg); -} -.sk-spinner-circle .sk-circle12 { - -webkit-transform: rotate(330deg); - -ms-transform: rotate(330deg); - transform: rotate(330deg); -} -.sk-spinner-circle .sk-circle2:before { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} -.sk-spinner-circle .sk-circle3:before { - -webkit-animation-delay: -1s; - animation-delay: -1s; -} -.sk-spinner-circle .sk-circle4:before { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} -.sk-spinner-circle .sk-circle5:before { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} -.sk-spinner-circle .sk-circle6:before { - -webkit-animation-delay: -0.7s; - animation-delay: -0.7s; -} -.sk-spinner-circle .sk-circle7:before { - -webkit-animation-delay: -0.6s; - animation-delay: -0.6s; -} -.sk-spinner-circle .sk-circle8:before { - -webkit-animation-delay: -0.5s; - animation-delay: -0.5s; -} -.sk-spinner-circle .sk-circle9:before { - -webkit-animation-delay: -0.4s; - animation-delay: -0.4s; -} -.sk-spinner-circle .sk-circle10:before { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; -} -.sk-spinner-circle .sk-circle11:before { - -webkit-animation-delay: -0.2s; - animation-delay: -0.2s; -} -.sk-spinner-circle .sk-circle12:before { - -webkit-animation-delay: -0.1s; - animation-delay: -0.1s; -} -@-webkit-keyframes sk-circleBounceDelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 40% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -@keyframes sk-circleBounceDelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); - } - 40% { - -webkit-transform: scale(1); - transform: scale(1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-cube-grid"> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * <div class="sk-cube"></div> - * </div> - * - */ -.sk-spinner-cube-grid { - /* - * Spinner positions - * 1 2 3 - * 4 5 6 - * 7 8 9 - */ -} -.sk-spinner-cube-grid.sk-spinner { - width: 30px; - height: 30px; - margin: 0 auto; -} -.sk-spinner-cube-grid .sk-cube { - width: 33%; - height: 33%; - background-color: #007C82; - float: left; - -webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; - animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; -} -.sk-spinner-cube-grid .sk-cube:nth-child(1) { - -webkit-animation-delay: 0.2s; - animation-delay: 0.2s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(2) { - -webkit-animation-delay: 0.3s; - animation-delay: 0.3s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(3) { - -webkit-animation-delay: 0.4s; - animation-delay: 0.4s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(4) { - -webkit-animation-delay: 0.1s; - animation-delay: 0.1s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(5) { - -webkit-animation-delay: 0.2s; - animation-delay: 0.2s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(6) { - -webkit-animation-delay: 0.3s; - animation-delay: 0.3s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(7) { - -webkit-animation-delay: 0s; - animation-delay: 0s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(8) { - -webkit-animation-delay: 0.1s; - animation-delay: 0.1s; -} -.sk-spinner-cube-grid .sk-cube:nth-child(9) { - -webkit-animation-delay: 0.2s; - animation-delay: 0.2s; -} -@-webkit-keyframes sk-cubeGridScaleDelay { - 0%, - 70%, - 100% { - -webkit-transform: scale3D(1, 1, 1); - transform: scale3D(1, 1, 1); - } - 35% { - -webkit-transform: scale3D(0, 0, 1); - transform: scale3D(0, 0, 1); - } -} -@keyframes sk-cubeGridScaleDelay { - 0%, - 70%, - 100% { - -webkit-transform: scale3D(1, 1, 1); - transform: scale3D(1, 1, 1); - } - 35% { - -webkit-transform: scale3D(0, 0, 1); - transform: scale3D(0, 0, 1); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-wordpress"> - * <span class="sk-inner-circle"></span> - * </div> - * - */ -.sk-spinner-wordpress.sk-spinner { - background-color: #007C82; - width: 30px; - height: 30px; - border-radius: 30px; - position: relative; - margin: 0 auto; - -webkit-animation: sk-innerCircle 1s linear infinite; - animation: sk-innerCircle 1s linear infinite; -} -.sk-spinner-wordpress .sk-inner-circle { - display: block; - background-color: #fff; - width: 8px; - height: 8px; - position: absolute; - border-radius: 8px; - top: 5px; - left: 5px; -} -@-webkit-keyframes sk-innerCircle { - 0% { - -webkit-transform: rotate(0); - transform: rotate(0); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@keyframes sk-innerCircle { - 0% { - -webkit-transform: rotate(0); - transform: rotate(0); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -/* - * Usage: - * - * <div class="sk-spinner sk-spinner-fading-circle"> - * <div class="sk-circle1 sk-circle"></div> - * <div class="sk-circle2 sk-circle"></div> - * <div class="sk-circle3 sk-circle"></div> - * <div class="sk-circle4 sk-circle"></div> - * <div class="sk-circle5 sk-circle"></div> - * <div class="sk-circle6 sk-circle"></div> - * <div class="sk-circle7 sk-circle"></div> - * <div class="sk-circle8 sk-circle"></div> - * <div class="sk-circle9 sk-circle"></div> - * <div class="sk-circle10 sk-circle"></div> - * <div class="sk-circle11 sk-circle"></div> - * <div class="sk-circle12 sk-circle"></div> - * </div> - * - */ -.sk-spinner-fading-circle.sk-spinner { - margin: 0 auto; - width: 22px; - height: 22px; - position: relative; -} -.sk-spinner-fading-circle .sk-circle { - width: 100%; - height: 100%; - position: absolute; - left: 0; - top: 0; -} -.sk-spinner-fading-circle .sk-circle:before { - content: ''; - display: block; - margin: 0 auto; - width: 18%; - height: 18%; - background-color: #007C82; - border-radius: 100%; - -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out; - animation: sk-circleFadeDelay 1.2s infinite ease-in-out; - /* Prevent first frame from flickering when animation starts */ - -webkit-animation-fill-mode: both; - animation-fill-mode: both; -} -.sk-spinner-fading-circle .sk-circle2 { - -webkit-transform: rotate(30deg); - -ms-transform: rotate(30deg); - transform: rotate(30deg); -} -.sk-spinner-fading-circle .sk-circle3 { - -webkit-transform: rotate(60deg); - -ms-transform: rotate(60deg); - transform: rotate(60deg); -} -.sk-spinner-fading-circle .sk-circle4 { - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.sk-spinner-fading-circle .sk-circle5 { - -webkit-transform: rotate(120deg); - -ms-transform: rotate(120deg); - transform: rotate(120deg); -} -.sk-spinner-fading-circle .sk-circle6 { - -webkit-transform: rotate(150deg); - -ms-transform: rotate(150deg); - transform: rotate(150deg); -} -.sk-spinner-fading-circle .sk-circle7 { - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.sk-spinner-fading-circle .sk-circle8 { - -webkit-transform: rotate(210deg); - -ms-transform: rotate(210deg); - transform: rotate(210deg); -} -.sk-spinner-fading-circle .sk-circle9 { - -webkit-transform: rotate(240deg); - -ms-transform: rotate(240deg); - transform: rotate(240deg); -} -.sk-spinner-fading-circle .sk-circle10 { - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} -.sk-spinner-fading-circle .sk-circle11 { - -webkit-transform: rotate(300deg); - -ms-transform: rotate(300deg); - transform: rotate(300deg); -} -.sk-spinner-fading-circle .sk-circle12 { - -webkit-transform: rotate(330deg); - -ms-transform: rotate(330deg); - transform: rotate(330deg); -} -.sk-spinner-fading-circle .sk-circle2:before { - -webkit-animation-delay: -1.1s; - animation-delay: -1.1s; -} -.sk-spinner-fading-circle .sk-circle3:before { - -webkit-animation-delay: -1s; - animation-delay: -1s; -} -.sk-spinner-fading-circle .sk-circle4:before { - -webkit-animation-delay: -0.9s; - animation-delay: -0.9s; -} -.sk-spinner-fading-circle .sk-circle5:before { - -webkit-animation-delay: -0.8s; - animation-delay: -0.8s; -} -.sk-spinner-fading-circle .sk-circle6:before { - -webkit-animation-delay: -0.7s; - animation-delay: -0.7s; -} -.sk-spinner-fading-circle .sk-circle7:before { - -webkit-animation-delay: -0.6s; - animation-delay: -0.6s; -} -.sk-spinner-fading-circle .sk-circle8:before { - -webkit-animation-delay: -0.5s; - animation-delay: -0.5s; -} -.sk-spinner-fading-circle .sk-circle9:before { - -webkit-animation-delay: -0.4s; - animation-delay: -0.4s; -} -.sk-spinner-fading-circle .sk-circle10:before { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; -} -.sk-spinner-fading-circle .sk-circle11:before { - -webkit-animation-delay: -0.2s; - animation-delay: -0.2s; -} -.sk-spinner-fading-circle .sk-circle12:before { - -webkit-animation-delay: -0.1s; - animation-delay: -0.1s; -} -@-webkit-keyframes sk-circleFadeDelay { - 0%, - 39%, - 100% { - opacity: 0; - } - 40% { - opacity: 1; - } -} -@keyframes sk-circleFadeDelay { - 0%, - 39%, - 100% { - opacity: 0; - } - 40% { - opacity: 1; - } -} - - - - - - - - -body.md-skin { - font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; - background-color: #ffffff; -} -.md-skin .nav-header { - background: url("../images/4.png") no-repeat; -} -.md-skin .label, -.md-skin .badge { - font-family: 'Roboto'; -} -.md-skin .font-bold { - font-weight: 500; -} -.md-skin .wrapper-content { - padding: 30px 20px 40px; -} -@media (max-width: 768px) { - .md-skin .wrapper-content { - padding: 30px 0 40px; - } -} -.md-skin .page-heading { - border-bottom: none !important; - border-top: 0; - padding: 0 10px 20px 10px; - box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.34), 0 0 6px 0 rgba(0, 0, 0, 0.14); -} -.md-skin .full-height-layout .page-heading { - border-bottom: 1px solid #e7eaec !important; -} -.md-skin .ibox { - clear: both; - margin-bottom: 15px; - margin-top: 0; - padding: 0; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.central { text-align:center; } -.md-skin .ibox .icon { - width:120px ; height:120px; - padding-bottom: 5px; - display: block; - margin: 0 auto; -} -.pdx-singleLine{ - font-size:11px; - width: 100%; height: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - text-align:center; -} - -pdxSmall{ - font-size:10px; -} - - - - - -/* -.md-skin .ibox im { - display: block; - margin: 0 auto; - border:1px solid #000; -}*/ -.md-skin .ibox.border-bottom { - border-bottom: none !important; -} -.md-skin .ibox-title, -.md-skin .ibox-content { - border-style: none; -} -.md-skin .ibox-title h5 { - font-size: 16px; - font-weight: 400; -} -.md-skin a.close-canvas-menu { - color: #ffffff; -} -.md-skin .welcome-message { - color: #ffffff; - font-weight: 300; -} -.md-skin #top-search::-moz-placeholder { - color: #ffffff; -} -.md-skin #top-search::-webkit-input-placeholder { - color: #ffffff; -} -.md-skin #nestable-output, -.md-skin #nestable2-output { - font-family: 'Roboto', lucida grande, lucida sans unicode, helvetica, arial, sans-serif; -} -.md-skin .landing-page { - font-family: 'Roboto', helvetica, arial, sans-serif; -} -.md-skin .landing-page.navbar-default.navbar-scroll { - background-color: #fff !important; -} -.md-skin .landing-page.navbar-default { - background-color: transparent !important; - box-shadow: none; -} -.md-skin .landing-page.navbar-default .nav li a { - font-family: 'Roboto', helvetica, arial, sans-serif; -} -.md-skin .nav > li > a { - color: #676a6c; - padding: 14px 20px 14px 25px; -} -.md-skin .nav.navbar-right > li > a { - color: #ffffff; -} -.md-skin .nav > li.active > a { - color: #5b5d5f; - font-weight: 700; -} -.md-skin .navbar-default .nav > li > a:hover, -.md-skin .navbar-default .nav > li > a:focus { - font-weight: 700; - color: #5b5d5f; -} -.md-skin .nav .open > a, -.md-skin .nav .open > a:hover, -.md-skin .nav .open > a:focus { - background: #007C82; -} -.md-skin .navbar-top-links li { - display: inline-table; -} -.md-skin .navbar-top-links .dropdown-menu li { - display: block; -} -.md-skin .pace-done .nav-header { - transition: all 0.4s; -} -.md-skin .nav > li.active { - background: #f8f8f9; -} -.md-skin .nav-second-level li a { - padding: 7px 10px 7px 52px; -} -.md-skin .navbar-top-links li a { - padding: 20px 10px; - min-height: 50px; -} -.md-skin .nav > li > a { - font-weight: 400; -} -.md-skin .navbar-static-side .nav > li > a:focus, -.md-skin .navbar-static-side .nav > li > a:hover { - background-color: inherit; -} -.md-skin .navbar-top-links .dropdown-menu li a { - padding: 3px 20px; - min-height: inherit; -} -.md-skin .nav-header .navbar-fixed-top a { - color: #ffffff; -} -.md-skin .nav-header .text-muted { - color: #ffffff; -} -.md-skin .navbar-form-custom .form-control { - font-weight: 300; -} -.md-skin .mini-navbar .nav-second-level { - background-color: inherit; -} -.md-skin .mini-navbar li.active .nav-second-level { - left: 65px; -} -.md-skin .canvas-menu.mini-navbar .nav-second-level { - background: inherit; -} -.md-skin .pace-done .navbar-static-side, -.md-skin .pace-done .nav-header, -.md-skin .pace-done li.active, -.md-skin .pace-done #page-wrapper, -.md-skin .pace-done .footer { - -webkit-transition: all 0.4s; - -moz-transition: all 0.4s; - -o-transition: all 0.4s; - transition: all 0.4s; -} -.md-skin .navbar-fixed-top { - background: #fff; - transition-duration: 0.4s; - z-index: 2030; - border-bottom: none !important; -} -.md-skin .navbar-fixed-top, -.md-skin .navbar-static-top { - background-color: #007C82 !important; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin .navbar-static-side { - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin #right-sidebar { - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - border: none; - z-index: 900; -} -.md-skin .white-bg .navbar-fixed-top, -.md-skin .white-bg .navbar-static-top { - background: #fff !important; -} -.md-skin .contact-box { - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - border: none; -} -.md-skin .dashboard-header { - border-bottom: none !important; - border-top: 0; - padding: 20px 20px 20px 20px; - margin: 30px 20px 0 20px; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -@media (max-width: 768px) { - .md-skin .dashboard-header { - margin: 20px 0 0 0; - } -} -.md-skin ul.notes li div { - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin .file { - border: none; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin .mail-box { - background-color: #ffffff; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - padding: 0; - margin-bottom: 20px; - border: none; -} -.md-skin .mail-box-header { - border: none; - background-color: #ffffff; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - padding: 30px 20px 20px 20px; -} -.md-skin .mailbox-content { - border: none; - padding: 20px; - background: #ffffff; -} -.md-skin .social-feed-box { - border: none; - background: #fff; - margin-bottom: 15px; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin.landing-page .navbar-default { - background-color: transparent !important; - border-color: transparent; - transition: all 0.3s ease-in-out 0s; - box-shadow: none; -} -.md-skin.landing-page .navbar-default.navbar-scroll, -.md-skin.landing-page.body-small .navbar-default { - background-color: #ffffff !important; -} -.md-skin.landing-page .nav > li.active { - background: inherit; -} -.md-skin.landing-page .navbar-scroll .navbar-nav > li > a { - padding: 20px 10px; -} -.md-skin.landing-page .navbar-default .nav li a { - font-family: 'Roboto', helvetica, arial, sans-serif; -} -.md-skin.landing-page .nav > li > a { - padding: 25px 10px 15px 10px; -} -.md-skin.landing-page .navbar-default .navbar-nav > li > a:hover, -.md-skin.landing-page .navbar-default .navbar-nav > li > a:focus { - background: inherit; - color: #007C82; -} -.md-skin.landing-page.body-small .nav.navbar-right > li > a { - color: #676a6c; -} -.md-skin .landing_link a, -.md-skin .special_link a { - color: #ffffff !important; -} -.md-skin.canvas-menu.mini-navbar .nav-second-level { - background: #f8f8f9; -} -.md-skin.mini-navbar .nav-second-level { - background-color: #ffffff; - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); -} -.md-skin.mini-navbar .nav-second-level li a { - padding-left: 0; -} -.md-skin.mini-navbar.fixed-sidebar .nav-second-level li a { - padding-left: 52px; -} -.md-skin.mini-navbar.canvas-menu .nav-second-level li a { - padding-left: 52px; -} -.md-skin.top-navigation .nav.navbar-right > li > a { - padding: 15px 20px; - color: #676a6c; -} -.md-skin.top-navigation .nav > li a:hover, -.md-skin .top-navigation .nav > li a:focus, -.md-skin.top-navigation .nav .open > a, -.md-skin.top-navigation .nav .open > a:hover, -.md-skin.top-navigation .nav .open > a:focus { - color: #007C82; - background: #ffffff; -} -.md-skin.top-navigation .nav > li.active a { - color: #007C82; - background: #ffffff; -} -.md-skin.fixed-nav #wrapper.top-navigation #page-wrapper { - margin-top: 0; -} -.md-skin.fixed-sidebar.mini-navbar .navbar-static-side { - width: 0; -} -.md-skin.fixed-sidebar.mini-navbar #page-wrapper { - margin: 0 0 0 0; -} -.md-skin.body-small.fixed-sidebar.mini-navbar #page-wrapper { - margin: 0 0 0 0; -} -.md-skin.body-small.fixed-sidebar.mini-navbar .navbar-static-side { - width: 220px; - background-color: #ffffff; -} -.md-skin.canvas-menu nav.navbar-static-side { - z-index: 2001; - background: #ffffff; - height: 100%; - position: fixed; - display: none; -} -@media (min-width: 768px) { - #page-wrapper { - position: inherit; - margin: 0 0 0 220px; - min-height: 1200px; - } - .navbar-static-side { - z-index: 2001; - position: absolute; - width: 220px; - } - .navbar-top-links .dropdown-messages, - .navbar-top-links .dropdown-tasks, - .navbar-top-links .dropdown-alerts { - margin-left: auto; - } -} -@media (max-width: 768px) { - #page-wrapper { - position: inherit; - margin: 0 0 0 0; - min-height: 1000px; - } - .body-small .navbar-static-side { - display: none; - z-index: 2001; - position: absolute; - width: 70px; - } - .body-small.mini-navbar .navbar-static-side { - display: block; - } - .lock-word { - display: none; - } - .navbar-form-custom { - display: none; - } - .navbar-header { - display: inline; - float: left; - } - .sidebard-panel { - z-index: 2; - position: relative; - width: auto; - min-height: 100% !important; - } - .sidebar-content .wrapper { - padding-right: 0; - z-index: 1; - } - .fixed-sidebar.body-small .navbar-static-side { - display: none; - z-index: 2001; - position: fixed; - width: 220px; - } - .fixed-sidebar.body-small.mini-navbar .navbar-static-side { - display: block; - } - .ibox-tools { - float: none; - text-align: right; - display: block; - } -} -@media (max-width: 350px) { - .timeline-item .date { - text-align: left; - width: 110px; - position: relative; - padding-top: 30px; - } - .timeline-item .date i { - position: absolute; - top: 0; - left: 15px; - padding: 5px; - width: 30px; - text-align: center; - border: 1px solid #e7eaec; - background: #f8f8f8; - } - .timeline-item .content { - border-left: none; - border-top: 1px solid #e7eaec; - padding-top: 10px; - min-height: 100px; - } - .nav.navbar-top-links li.dropdown { - display: none; - } - .ibox-tools { - float: none; - text-align: left; - display: inline-block; - } -} -/* Only demo */ -@media (max-width: 1000px) { - .welcome-message { - display: none; - } -} -@media print { - nav.navbar-static-side { - display: none; - } - #page-wrapper { - margin: 0; - } -} diff --git a/admin/src/main/resources/static/fonts/FontAwesome.otf b/admin/src/main/resources/static/fonts/FontAwesome.otf deleted file mode 100755 index f7936cc1e789eea5438d576d6b12de20191da09d..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/fonts/FontAwesome.otf and /dev/null differ diff --git a/admin/src/main/resources/static/fonts/fontawesome-webfont.eot b/admin/src/main/resources/static/fonts/fontawesome-webfont.eot deleted file mode 100755 index 33b2bb80055cc480e797de704925acaba4ba7d7d..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/admin/src/main/resources/static/fonts/fontawesome-webfont.svg b/admin/src/main/resources/static/fonts/fontawesome-webfont.svg deleted file mode 100755 index 1ee89d4368d31a368817a842f14d53f7a64c3038..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,565 +0,0 @@ -<?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" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"> -<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="	" horiz-adv-x="448" /> -<glyph unicode=" " horiz-adv-x="448" /> -<glyph unicode="¨" horiz-adv-x="1792" /> -<glyph unicode="©" horiz-adv-x="1792" /> -<glyph unicode="®" horiz-adv-x="1792" /> -<glyph unicode="´" horiz-adv-x="1792" /> -<glyph unicode="Æ" horiz-adv-x="1792" /> -<glyph unicode="Ø" horiz-adv-x="1792" /> -<glyph unicode=" " horiz-adv-x="768" /> -<glyph unicode=" " horiz-adv-x="1537" /> -<glyph unicode=" " horiz-adv-x="768" /> -<glyph unicode=" " horiz-adv-x="1537" /> -<glyph unicode=" " horiz-adv-x="512" /> -<glyph unicode=" " horiz-adv-x="384" /> -<glyph unicode=" " horiz-adv-x="256" /> -<glyph unicode=" " horiz-adv-x="256" /> -<glyph unicode=" " horiz-adv-x="192" /> -<glyph unicode=" " horiz-adv-x="307" /> -<glyph unicode=" " horiz-adv-x="85" /> -<glyph unicode=" " horiz-adv-x="307" /> -<glyph unicode=" " horiz-adv-x="384" /> -<glyph unicode="™" horiz-adv-x="1792" /> -<glyph unicode="∞" horiz-adv-x="1792" /> -<glyph unicode="≠" horiz-adv-x="1792" /> -<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1699 1350q0 -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 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> -<glyph unicode="" d="M1536 1312v-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.5q105 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 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -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.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-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-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -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 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 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 -600 q-18 -18 -44 -18z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 889q0 -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 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -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 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 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 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -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.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -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.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " /> -<glyph unicode="" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 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.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-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 108q-44 -23 -91 -38 q-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.5v222q0 12 8 23t19 13 l186 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 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-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.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z " /> -<glyph unicode="" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 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 -116z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> -<glyph unicode="" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" /> -<glyph unicode="" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1536 1280v-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.5t-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 -9 l137 -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 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> -<glyph unicode="" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" /> -<glyph unicode="" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M320 1280q0 -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 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 650q0 -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-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-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 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> -<glyph unicode="" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> -<glyph unicode="" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> -<glyph unicode="" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -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.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1639 1058q40 -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 127q0 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 23 q21 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 23t17 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 -906 q-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 57q38 -15 59 -43zM575 1056q-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.5 t-16.5 -22.5zM492 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.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1164 1408q23 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 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> -<glyph unicode="" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 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.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M725 977l-170 -450q33 0 136.5 -2t160.5 -2q19 0 57 2q-87 253 -184 452zM0 -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 -57 q19 -15 88 -29.5t84 -20.5q6 -38 6 -57q0 -4 -0.5 -13t-0.5 -13q-63 0 -190 8t-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.5 q0 -22 14 -37.5t43.5 -24.5t48.5 -13.5t57 -8.5t41 -4q1 -19 1 -58q0 -9 -2 -27q-58 0 -174.5 10t-174.5 10q-8 0 -26.5 -4t-21.5 -4q-80 -14 -188 -14z" /> -<glyph unicode="" horiz-adv-x="1408" d="M555 15q74 -32 140 -32q376 0 376 335q0 114 -41 180q-27 44 -61.5 74t-67.5 46.5t-80.5 25t-84 10.5t-94.5 2q-73 0 -101 -10q0 -53 -0.5 -159t-0.5 -158q0 -8 -1 -67.5t-0.5 -96.5t4.5 -83.5t12 -66.5zM541 761q42 -7 109 -7q82 0 143 13t110 44.5t74.5 89.5t25.5 142 q0 70 -29 122.5t-79 82t-108 43.5t-124 14q-50 0 -130 -13q0 -50 4 -151t4 -152q0 -27 -0.5 -80t-0.5 -79q0 -46 1 -69zM0 -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.5 t-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.5t28 -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.5 t-176 -14q-44 0 -132 3t-132 3q-106 0 -307 -11t-231 -12z" /> -<glyph unicode="" 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="" horiz-adv-x="1792" d="M1744 128q33 0 42 -18.5t-11 -44.5l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80zM81 1407l54 -27q12 -5 211 -5q44 0 132 2 t132 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.5q-6 8 -12 12.5t-15.5 6t-13 2.5t-18 0.5t-16.5 -0.5 q-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 -9t-152 -9q-3 51 -3 52v9q17 27 61.5 43t98.5 29t78 27 q19 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 44v383z" /> -<glyph unicode="" d="M81 1407l54 -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 1t-103 1 t-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 29t78 27 q7 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 44v383zM1310 125q12 0 42 -19.5t57.5 -41.5 t59.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.5t-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 49 t26 49q4 3 36 30t59.5 49t57.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.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 1184v-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.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" /> -<glyph unicode="" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> -<glyph unicode="" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M512 384q0 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 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 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 -275z" /> -<glyph unicode="" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 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 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 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 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-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.5 t-38.5 114t-17.5 122q0 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 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 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-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-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 45 t19 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 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M979 1395q19 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 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1747 1395q19 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 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1619 1395q19 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 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> -<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 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 -19z" /> -<glyph unicode="" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 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 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" /> -<glyph unicode="" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 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 -19z" /> -<glyph unicode="" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1171 1235l-531 -531l531 -531q19 -19 19 -45t-19 -45l-166 -166q-19 -19 -45 -19t-45 19l-742 742q-19 19 -19 45t19 45l742 742q19 19 45 19t45 -19l166 -166q19 -19 19 -45t-19 -45z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1107 659l-742 -742q-19 -19 -45 -19t-45 19l-166 166q-19 19 -19 45t19 45l531 531l-531 531q-19 19 -19 45t19 45l166 166q19 19 45 19t45 -19l742 -742q19 -19 19 -45t-19 -45z" /> -<glyph unicode="" d="M1216 576v128q0 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-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" /> -<glyph unicode="" d="M1149 414q0 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 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -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 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1197 512h-109q-26 0 -45 19t-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-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 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 -45z" /> -<glyph unicode="" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 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 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> -<glyph unicode="" d="M1536 640v-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 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" /> -<glyph unicode="" d="M1472 576q0 -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.5v128q0 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 -90z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 565q0 -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 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 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 -91z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 896q0 -26 -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 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> -<glyph unicode="" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-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 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1482 486q46 -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.5t59.5 77.5l266 154l-266 154 q-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.5l-266 -154z" /> -<glyph unicode="" d="M768 1408q209 0 385.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.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> -<glyph unicode="" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 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.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-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.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.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 -96z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -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 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 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 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -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 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> -<glyph unicode="" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-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 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> -<glyph unicode="" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 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 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-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 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -174 -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.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> -<glyph unicode="" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 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 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1683 205l-166 -165q-19 -19 -45 -19t-45 19l-531 531l-531 -531q-19 -19 -45 -19t-45 19l-166 165q-19 19 -19 45.5t19 45.5l742 741q19 19 45 19t45 -19l742 -741q19 -19 19 -45.5t-19 -45.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1683 728l-742 -741q-19 -19 -45 -19t-45 19l-742 741q-19 19 -19 45.5t19 45.5l166 165q19 19 45 19t45 -19l531 -531l531 531q19 19 45 19t45 -19l166 -165q19 -19 19 -45.5t-19 -45.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 32q0 -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 45q0 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 -21 zM1920 448q0 -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 20q0 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 -45z " /> -<glyph unicode="" horiz-adv-x="1664" d="M640 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1536 0q0 -52 -38 -90t-90 -38t-90 38t-38 90t38 90t90 38t90 -38t38 -90zM1664 1088v-512q0 -24 -16.5 -42.5t-40.5 -21.5l-1044 -122q13 -60 13 -70q0 -16 -24 -64h920q26 0 45 -19t19 -45 t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 11 8 31.5t16 36t21.5 40t15.5 29.5l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t19.5 -15.5t13 -24.5t8 -26t5.5 -29.5t4.5 -26h1201q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="768" d="M704 1216q0 -26 -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 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -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 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="2048" d="M640 640v-512h-256v512h256zM1024 1152v-1024h-256v1024h256zM2048 0v-128h-2048v1536h128v-1408h1920zM1408 896v-768h-256v768h256zM1792 1280v-1152h-256v1152h256z" /> -<glyph unicode="" d="M1280 926q-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 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-188v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-532q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960z" /> -<glyph unicode="" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-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.5q0 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.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> -<glyph unicode="" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-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 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-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.5v185q0 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 -7 l115 -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 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-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 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 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 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-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 31v140q0 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 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1408 768q0 -139 -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 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -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 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> -<glyph unicode="" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.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 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -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.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 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 -179z" /> -<glyph unicode="" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -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.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-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.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 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 -163z" /> -<glyph unicode="" horiz-adv-x="896" d="M832 1504v-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 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 940q0 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.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -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 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 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-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> -<glyph unicode="" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -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 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 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 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-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.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-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 -91 t97.5 -37q75 0 133.5 -45.5t58.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 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> -<glyph unicode="" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-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 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-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 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-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.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> -<glyph unicode="" d="M1407 710q0 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 24q-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.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 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 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-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.5q0 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 5 q81 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.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-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.5 q0 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 -235t235 -174 q2 -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 -21z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 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 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> -<glyph unicode="" d="M1280 343q0 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.5t-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.5 t45 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.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1620 1128q-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 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 -41 q-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.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> -<glyph unicode="" horiz-adv-x="1024" d="M959 1524v-264h-157q-86 0 -116 -36t-30 -108v-189h293l-39 -296h-254v-759h-306v759h-255v296h255v218q0 186 104 288.5t277 102.5q147 0 228 -12z" /> -<glyph unicode="" d="M1536 640q0 -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 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-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 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -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.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 960v-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-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -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 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" /> -<glyph unicode="" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 896q53 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 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> -<glyph unicode="" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM246 128h1300q-266 300 -266 832q0 51 -24 105t-69 103t-121.5 80.5t-169.5 31.5t-169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -532 -266 -832z M1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5 t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> -<glyph unicode="" d="M1376 640l138 -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 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-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 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> -<glyph unicode="" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 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 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.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 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -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.5v640q0 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.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1376 128h32v640h-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.5t-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-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -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 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 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.5z" /> -<glyph unicode="" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 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-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-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.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> -<glyph unicode="" d="M1408 576q0 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 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.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.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-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.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 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 -317z" /> -<glyph unicode="" d="M1280 576v128q0 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 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1285 640q0 27 -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-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1284 639q0 27 -18 45l-91 91q-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 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M768 1408q209 0 385.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.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-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 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 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.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-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.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-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.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-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 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-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 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-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 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-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.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -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 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-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 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-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.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.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 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 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 7t-10 1.5t-11.5 -7 q-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.5q0 -6 2 -16z" /> -<glyph unicode="" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.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 -25z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1403 1241q17 -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 70q17 39 59 39h1280q42 0 59 -39z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> -<glyph unicode="" d="M1283 995l-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 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 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 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " /> -<glyph unicode="" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 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.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1456 320q0 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.5q0 -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 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -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 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 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.5z " /> -<glyph unicode="" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> -<glyph unicode="" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -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 207q7 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 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 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 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-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 -235 z" /> -<glyph unicode="" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> -<glyph unicode="" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 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 -88zM383 543v-159h-362 q-6 36 -6 54q0 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.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -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 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> -<glyph unicode="" d="M48 1313q-37 2 -45 4l-3 88q13 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.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 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 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -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 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> -<glyph unicode="" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -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.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1536 640q0 -209 -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 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -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.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1248 1408q119 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.5q-104 0 -194.5 -28.5t-153 -76.5 t-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 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.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.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> -<glyph unicode="" d="M829 318q0 -76 -58.5 -112.5t-139.5 -36.5q-41 0 -80.5 9.5t-75.5 28.5t-58 53t-22 78q0 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.5zM755 863q0 -60 -33 -99.5t-92 -39.5q-53 0 -93 42.5 t-57.5 96.5t-17.5 106q0 61 32 104t92 43q53 0 93.5 -45t58 -101t17.5 -107zM861 1120l88 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 -94q-175 -12 -257 -63q-47 -29 -75.5 -73t-28.5 -95 q0 -43 18.5 -77.5t48.5 -56.5t69 -37t77.5 -21t76.5 -6q60 0 120.5 15.5t113.5 46t86 82.5t33 117q0 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.5h83zM1152 672h128v64h-128v128h-64v-128 h-128v-64h128v-160h64v160zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M735 740q0 -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 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 42 -47.5 74t-15.5 73q0 36 21 85q-46 -4 -68 -4 q-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 -65t-59.5 -61.5t-24.5 -66zM589 836q38 0 78 16.5t66 43.5q53 57 53 159q0 58 -17 125t-48.5 129.5 t-84.5 103.5t-117 41q-42 0 -82.5 -19.5t-65.5 -52.5q-47 -59 -47 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26zM591 -37q58 0 111.5 13t99 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 -48 2 q-53 0 -105 -7t-107.5 -25t-97 -46t-68.5 -74.5t-27 -105.5q0 -70 35 -123.5t91.5 -83t119 -44t127.5 -14.5zM1401 839h213v-108h-213v-219h-105v219h-212v108h212v217h105v-217z" /> -<glyph unicode="" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -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 87zM1792 1120q0 -79 -49 -151t-122 -123 q-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.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> -<glyph unicode="" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-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-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> -<glyph unicode="" d="M1536 640q0 -156 -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 -12q73 -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.5 t-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 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1771 0q0 -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.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 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 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 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 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -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.5zM1792 640 q0 -174 -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.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -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 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-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 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -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 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> -<glyph unicode="" horiz-adv-x="896" d="M885 970q18 -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 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 288v-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 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 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 -68 z" /> -<glyph unicode="" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-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 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 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 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> -<glyph unicode="" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -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 -47 q0 -46 -31.5 -71t-77.5 -25q-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 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 352v-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 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 608q0 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.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 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.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -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.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 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.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 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 -56 t136 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-89q-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 -68 t68 -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.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 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 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" /> -<glyph unicode="" horiz-adv-x="1792" d="M912 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1728 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q50 42 91 88t85 119.5t74.5 158.5 t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q190 -28 307 -158.5t117 -282.5q0 -139 19.5 -260t50 -206t74.5 -158.5t85 -119.5t91 -88z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M384 736q0 14 9 23t23 9h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64zM1120 512q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704zM1120 256q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704 q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 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.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 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-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -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-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 416v192q0 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-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> -<glyph unicode="" d="M1280 192v896q0 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-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1280 576v128q0 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-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 224q0 -13 -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 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 352q0 -13 -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 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> -<glyph unicode="" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> -<glyph unicode="" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> -<glyph unicode="" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 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 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 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 -136z" /> -<glyph unicode="" horiz-adv-x="1664" d="M768 1216v-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 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-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 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> -<glyph unicode="" horiz-adv-x="1792" d="M526 142q0 -53 -37.5 -90.5t-90.5 -37.5q-52 0 -90 38t-38 90q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1024 -64q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -53 -37.5 -90.5t-90.5 -37.5 t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1522 142q0 -52 -38 -90t-90 -38q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM558 1138q0 -66 -47 -113t-113 -47t-113 47t-47 113t47 113t113 47t113 -47t47 -113z M1728 640q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1088 1344q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1618 1138q0 -93 -66 -158.5t-158 -65.5q-93 0 -158.5 65.5t-65.5 158.5 q0 92 65.5 158t158.5 66q92 0 158 -66t66 -158z" /> -<glyph unicode="" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 416q0 -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 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> -<glyph unicode="" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 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 -218 q0 -87 -27 -168q136 -160 136 -398z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1134 307q8 -25 -4 -48.5t-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.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M832 448v128q0 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-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> -<glyph unicode="" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-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 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> -<glyph unicode="" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-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 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> -<glyph unicode="" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" /> -<glyph unicode="" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-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 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-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.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1401 1187l-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.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-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 136q0 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-497 q54 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 -136z" /> -<glyph unicode="" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> -<glyph unicode="" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -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.5 t-10.5 37.5v45q0 83 65 156.5t143 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 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> -<glyph unicode="" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> -<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 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 -63h232v80 h126z" /> -<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 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 -73h232v80h126z" /> -<glyph unicode="" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -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.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -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.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-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 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 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.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1152 832v-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 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> -<glyph unicode="" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-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-128 q0 -221 -147.5 -384.5t-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 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-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 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 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 -90z" /> -<glyph unicode="" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-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 45v800 q0 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 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -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 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> -<glyph unicode="" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> -<glyph unicode="" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> -<glyph unicode="" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-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.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 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-163h192q26 0 45 -19 t19 -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 -23z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 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 -181 v-320h736z" /> -<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> -<glyph unicode="" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> -<glyph unicode="" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M768 1408q209 0 385.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.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> -<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 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 -68z" /> -<glyph unicode="" horiz-adv-x="1024" d="M32 1280h704q13 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 34q9 19 29 19z" /> -<glyph unicode="" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1005 435l352 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.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M976 229l35 -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.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-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.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-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.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 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 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 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.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M978 351q0 -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.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.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 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.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 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" /> -<glyph unicode="" horiz-adv-x="898" d="M898 1066v-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 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 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 -144h171q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1027" d="M603 0h-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.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 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-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -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 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 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 -315z" /> -<glyph unicode="" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-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 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 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 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-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-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 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-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> -<glyph unicode="" d="M1024 1024v472q22 -14 36 -28l408 -408q14 -14 28 -36h-472zM896 992q0 -40 28 -68t68 -28h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544z" /> -<glyph unicode="" d="M1468 1060q14 -14 28 -36h-472v472q22 -14 36 -28zM992 896h544v-1056q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h800v-544q0 -40 28 -68t68 -28zM1152 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 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 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 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 1h248 v119h121z" /> -<glyph unicode="" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-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.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> -<glyph unicode="" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-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 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -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.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.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 -135z" /> -<glyph unicode="" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-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 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 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 -76z" /> -<glyph unicode="" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 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.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> -<glyph unicode="" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" /> -<glyph unicode="" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -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 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 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 -150z" /> -<glyph unicode="" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> -<glyph unicode="" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" /> -<glyph unicode="" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" /> -<glyph unicode="" d="M1248 1408q119 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.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> -<glyph unicode="" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-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 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-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 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 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 -54z" /> -<glyph unicode="" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M944 207l80 -237q-23 -35 -111 -66t-177 -32q-104 -2 -190.5 26t-142.5 74t-95 106t-55.5 120t-16.5 118v544h-168v215q72 26 129 69.5t91 90t58 102t34 99t15 88.5q1 5 4.5 8.5t7.5 3.5h244v-424h333v-252h-334v-518q0 -30 6.5 -56t22.5 -52.5t49.5 -41.5t81.5 -14 q78 2 134 29z" /> -<glyph unicode="" d="M1136 75l-62 183q-44 -22 -103 -22q-36 -1 -62 10.5t-38.5 31.5t-17.5 40.5t-5 43.5v398h257v194h-256v326h-188q-8 0 -9 -10q-5 -44 -17.5 -87t-39 -95t-77 -95t-118.5 -68v-165h130v-418q0 -57 21.5 -115t65 -111t121 -85.5t176.5 -30.5q69 1 136.5 25t85.5 50z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> -<glyph unicode="" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> -<glyph unicode="" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> -<glyph unicode="" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-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 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 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 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> -<glyph unicode="" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 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 18l-4 -5q-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 -54t7 -70.5q46 24 7 92 q-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.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 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 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-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.5q-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.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-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 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.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 195 q-12 112 -16 310q-2 90 24 151.5t106 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 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-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.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> -<glyph unicode="" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1173 473q0 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 -12t54 -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.5 t-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.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -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 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1000 1102l37 194q5 23 -9 40t-35 17h-712q-23 0 -38.5 -17t-15.5 -37v-1101q0 -7 6 -1l291 352q23 26 38 33.5t48 7.5h239q22 0 37 14.5t18 29.5q24 130 37 191q4 21 -11.5 40t-36.5 19h-294q-29 0 -48 19t-19 48v42q0 29 19 47.5t48 18.5h346q18 0 35 13.5t20 29.5z M1227 1324q-15 -73 -53.5 -266.5t-69.5 -350t-35 -173.5q-6 -22 -9 -32.5t-14 -32.5t-24.5 -33t-38.5 -21t-58 -10h-271q-13 0 -22 -10q-8 -9 -426 -494q-22 -25 -58.5 -28.5t-48.5 5.5q-55 22 -55 98v1410q0 55 38 102.5t120 47.5h888q95 0 127 -53t10 -159zM1227 1324 l-158 -790q4 17 35 173.5t69.5 350t53.5 266.5z" /> -<glyph unicode="" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1280 480q0 -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-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 832v-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 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-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 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-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 20q-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 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> -<glyph unicode="" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 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 -38z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-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 -207 q-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 45t19 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 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1917 1016q23 -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 12q-30 21 -70 64t-68.5 77.5t-61 58 t-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 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 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 24q17 19 38 30q53 26 239 24 q82 -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.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 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 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.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 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> -<glyph unicode="" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1402 433q-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 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-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 23t-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 -56 t16 -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 -89t-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.5 t112 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 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " /> -<glyph unicode="" d="M1152 640q0 -14 -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.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1152 736v-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 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 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.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> -<glyph unicode="" d="M1254 899q16 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 -143q-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 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1152" d="M1152 704q0 -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 26v128q0 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 9h160 q14 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 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-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 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="2176" d="M620 416q-110 -64 -268 -64h-128v64h-64q-13 0 -22.5 23.5t-9.5 56.5q0 24 7 49q-58 2 -96.5 10.5t-38.5 20.5t38.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 -40 t-22.5 -40t-83.5 -47.5t-150 -40.5q-16 -3 -80.5 -14t-106.5 -18h-1113zM1739 668q53 -36 53 -92t-53 -92l81 -30q68 48 68 122t-68 122zM625 400h1015q-217 -38 -456 -80q-57 0 -113 -24t-83 -48l-28 -24l-288 -288q-26 -26 -70.5 -45t-89.5 -19h-96l-93 464h29 q157 0 273 64zM352 816h-29l93 464h96q46 0 90 -19t70 -45l288 -288q4 -4 11 -10.5t30.5 -23t48.5 -29t61.5 -23t72.5 -10.5l456 -80h-1015q-116 64 -273 64z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1519 760q62 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 72l-55 163l-153 -53q-29 -9 -50 -9 q-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.5q0 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 102 t101.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.5t-74 -51.5l-157 -54l105 -316l164 56q24 8 46 8zM725 498l310 105l-105 315l-310 -107z" /> -<glyph unicode="" d="M1248 1408q119 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.5v960q0 119 84.5 203.5t203.5 84.5h960zM1280 352v436q-31 -35 -64 -55q-34 -22 -132.5 -85t-151.5 -99q-98 -69 -164 -69v0v0q-66 0 -164 69 q-46 32 -141.5 92.5t-142.5 92.5q-12 8 -33 27t-31 27v-436q0 -40 28 -68t68 -28h832q40 0 68 28t28 68zM1280 925q0 41 -27.5 70t-68.5 29h-832q-40 0 -68 -28t-28 -68q0 -37 30.5 -76.5t67.5 -64.5q47 -32 137.5 -89t129.5 -83q3 -2 17 -11.5t21 -14t21 -13t23.5 -13 t21.5 -9.5t22.5 -7.5t20.5 -2.5t20.5 2.5t22.5 7.5t21.5 9.5t23.5 13t21 13t21 14t17 11.5l267 174q35 23 66.5 62.5t31.5 73.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M127 640q0 163 67 313l367 -1005q-196 95 -315 281t-119 411zM1415 679q0 -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 -15t-1.5 -18.5t9 -16.5 t19.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.5q105 160 274.5 253.5t367.5 93.5q147 0 280.5 -53t238.5 -149h-10q-55 0 -92 -40.5t-37 -95.5q0 -12 2 -24t4 -21.5t8 -23t9 -21t12 -22.5t12.5 -21 t14.5 -24t14 -23q63 -107 63 -212zM909 573l237 -647q1 -6 5 -11q-126 -44 -255 -44q-112 0 -217 32zM1570 1009q95 -174 95 -369q0 -209 -104 -385.5t-279 -278.5l235 678q59 169 59 276q0 42 -6 79zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286 t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 -215q173 0 331.5 68t273 182.5t182.5 273t68 331.5t-68 331.5t-182.5 273t-273 182.5t-331.5 68t-331.5 -68t-273 -182.5t-182.5 -273t-68 -331.5t68 -331.5t182.5 -273 t273 -182.5t331.5 -68z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1086 1536v-1536l-272 -128q-228 20 -414 102t-293 208.5t-107 272.5q0 140 100.5 263.5t275 205.5t391.5 108v-172q-217 -38 -356.5 -150t-139.5 -255q0 -152 154.5 -267t388.5 -145v1360zM1755 954l37 -390l-525 114l147 83q-119 70 -280 99v172q277 -33 481 -157z" /> -<glyph unicode="" horiz-adv-x="2048" d="M960 1536l960 -384v-128h-128q0 -26 -20.5 -45t-48.5 -19h-1526q-28 0 -48.5 19t-20.5 45h-128v128zM256 896h256v-768h128v768h256v-768h128v768h256v-768h128v768h256v-768h59q28 0 48.5 -19t20.5 -45v-64h-1664v64q0 26 20.5 45t48.5 19h59v768zM1851 -64 q28 0 48.5 -19t20.5 -45v-128h-1920v128q0 26 20.5 45t48.5 19h1782z" /> -<glyph unicode="" horiz-adv-x="2304" d="M1774 700l18 -316q4 -69 -82 -128t-235 -93.5t-323 -34.5t-323 34.5t-235 93.5t-82 128l18 316l574 -181q22 -7 48 -7t48 7zM2304 1024q0 -23 -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 -433 q2 -14 -8 -25q-9 -11 -24 -11h-192q-15 0 -24 11q-10 11 -8 25l58 433q-58 38 -58 107q0 73 65 111q11 207 98 330l-333 104q-22 8 -22 31t22 31l1120 352q4 1 10 1t10 -1l1120 -352q22 -8 22 -31z" /> -<glyph unicode="" d="M859 579l13 -707q-62 11 -105 11q-41 0 -105 -11l13 707q-40 69 -168.5 295.5t-216.5 374.5t-181 287q58 -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 14v0 q-28 -39 -60 -88.5t-49.5 -78.5t-56.5 -96t-49 -84q-146 -248 -353 -610z" /> -<glyph unicode="" horiz-adv-x="1280" d="M981 197q0 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.5q0 -56 23.5 -102t61 -75.5t87 -50t100 -29t101.5 -8.5q58 0 111.5 13t99 39t73 73t27.5 109zM864 1055 q0 59 -17 125.5t-48 129t-84 103.5t-117 41q-42 0 -82.5 -19.5t-66.5 -52.5q-46 -59 -46 -160q0 -46 10 -97.5t31.5 -103t52 -92.5t75 -67t96.5 -26q37 0 77.5 16.5t65.5 43.5q53 56 53 159zM752 1536h417l-137 -88h-132q75 -63 113 -133t38 -160q0 -72 -24.5 -129.5 t-59.5 -93t-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 131q0 81 44.5 150t118.5 115q131 82 404 100q-32 41 -47.5 73.5 t-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 32z" /> -<glyph unicode="" horiz-adv-x="2304" d="M1509 107q0 -14 -12 -29q-52 -59 -147.5 -83t-196.5 -24q-252 0 -346 107q-12 15 -12 29q0 17 12 29.5t29 12.5q15 0 30 -12q58 -49 125.5 -66t159.5 -17t160 17t127 66q15 12 30 12q17 0 29 -12.5t12 -29.5zM978 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5 t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM1622 498q0 -61 -43 -104t-104 -43q-60 0 -104.5 43.5t-44.5 103.5q0 61 44 105t105 44t104 -44t43 -105zM415 793q-39 27 -88 27q-66 0 -113 -47t-47 -113q0 -72 54 -121q53 141 194 254zM2020 382q0 222 -249 387 q-128 85 -291.5 126.5t-331.5 41.5t-331.5 -41.5t-292.5 -126.5q-249 -165 -249 -387t249 -387q129 -85 292.5 -126.5t331.5 -41.5t331.5 41.5t291.5 126.5q249 165 249 387zM2137 660q0 66 -47 113t-113 47q-50 0 -93 -30q140 -114 192 -256q61 48 61 126zM1993 1335 q0 49 -34.5 83.5t-82.5 34.5q-49 0 -83.5 -34.5t-34.5 -83.5q0 -48 34.5 -82.5t83.5 -34.5q48 0 82.5 34.5t34.5 82.5zM2220 660q0 -65 -33 -122t-89 -90q5 -35 5 -66q0 -139 -79 -255.5t-208 -201.5q-140 -92 -313.5 -136.5t-354.5 -44.5t-355 44.5t-314 136.5 q-129 85 -208 201.5t-79 255.5q0 36 6 71q-53 33 -83.5 88.5t-30.5 118.5q0 100 71 171.5t172 71.5q91 0 159 -60q265 170 638 177l144 456q10 29 40 29q24 0 384 -90q24 55 74 88t110 33q82 0 141 -59t59 -142t-59 -141.5t-141 -58.5q-83 0 -141.5 58.5t-59.5 140.5 l-339 80l-125 -395q349 -15 603 -179q71 63 163 63q101 0 172 -71.5t71 -171.5z" /> -<glyph unicode="" d="M950 393q7 7 17.5 7t17.5 -7t7 -18t-7 -18q-65 -64 -208 -64h-1h-1q-143 0 -207 64q-8 7 -8 18t8 18q7 7 17.5 7t17.5 -7q49 -51 172 -51h1h1q122 0 173 51zM671 613q0 -37 -26 -64t-63 -27t-63 27t-26 64t26 63t63 26t63 -26t26 -63zM1214 1049q-29 0 -50 21t-21 50 q0 30 21 51t50 21q30 0 51 -21t21 -51q0 -29 -21 -50t-51 -21zM1216 1408q132 0 226 -94t94 -227v-894q0 -133 -94 -227t-226 -94h-896q-132 0 -226 94t-94 227v894q0 133 94 227t226 94h896zM1321 596q35 14 57 45.5t22 70.5q0 51 -36 87.5t-87 36.5q-60 0 -98 -48 q-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 43q-51 0 -87 -36.5t-36 -87.5q0 -37 19.5 -67.5t52.5 -45.5 q-7 -25 -7 -54q0 -98 74 -181.5t201.5 -132t278.5 -48.5q150 0 277.5 48.5t201.5 132t74 181.5q0 27 -6 54zM971 702q37 0 63 -26t26 -63t-26 -64t-63 -27t-63 27t-26 64t26 63t63 26z" /> -<glyph unicode="" d="M866 697l90 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-122q0 -82 57.5 -139t139.5 -57q81 0 138.5 56.5t57.5 136.5v280q0 19 13.5 33t33.5 14q19 0 32.5 -14t13.5 -33v-54zM1199 502v122h-150 v-126q0 -20 -13.5 -33.5t-33.5 -13.5q-19 0 -32.5 14t-13.5 33v123l-90 -26l-60 28v-123q0 -80 58 -137t139 -57t138.5 57t57.5 139zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103 t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1062 824v118q0 42 -30 72t-72 30t-72 -30t-30 -72v-612q0 -175 -126 -299t-303 -124q-178 0 -303.5 125.5t-125.5 303.5v266h328v-262q0 -43 30 -72.5t72 -29.5t72 29.5t30 72.5v620q0 171 126.5 292t301.5 121q176 0 302 -122t126 -294v-136l-195 -58zM1592 602h328 v-266q0 -178 -125.5 -303.5t-303.5 -125.5q-177 0 -303 124.5t-126 300.5v268l131 -61l195 58v-270q0 -42 30 -71.5t72 -29.5t72 29.5t30 71.5v275z" /> -<glyph unicode="" d="M1472 160v480h-704v704h-480q-93 0 -158.5 -65.5t-65.5 -158.5v-480h704v-704h480q93 0 158.5 65.5t65.5 158.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M328 1254h204v-983h-532v697h328v286zM328 435v369h-123v-369h123zM614 968v-697h205v697h-205zM614 1254v-204h205v204h-205zM901 968h533v-942h-533v163h328v82h-328v697zM1229 435v369h-123v-369h123zM1516 968h532v-942h-532v163h327v82h-327v697zM1843 435v369h-123 v-369h123z" /> -<glyph unicode="" d="M1046 516q0 -64 -38 -109t-91 -45q-43 0 -70 15v277q28 17 70 17q53 0 91 -45.5t38 -109.5zM703 944q0 -64 -38 -109.5t-91 -45.5q-43 0 -70 15v277q28 17 70 17q53 0 91 -45t38 -109zM1265 513q0 134 -88 229t-213 95q-20 0 -39 -3q-23 -78 -78 -136q-87 -95 -211 -101 v-636l211 41v206q51 -19 117 -19q125 0 213 95t88 229zM922 940q0 134 -88.5 229t-213.5 95q-74 0 -141 -36h-186v-840l211 41v206q55 -19 116 -19q125 0 213.5 95t88.5 229zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="2038" d="M1222 607q75 3 143.5 -20.5t118 -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 -14 q6 -5 28 -23.5t25.5 -22t19 -18t18 -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 -24 q-36 -53 -111.5 -99.5t-136.5 -46.5q-25 0 -75.5 63t-106.5 139.5t-84 96.5q-6 4 -27 30q-482 -112 -513 -112q-16 0 -28 11t-12 27q0 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 -33 q163 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 80t72 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.5 t31 -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.5zM1282 842q-5 5 -13.5 15.5t-12 14.5t-10.5 11.5t-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 -43 q16 30 36 46.5t54 29.5t65.5 36t46 36.5t50 55t43.5 50.5q12 -9 28 -31.5t32 -36.5t38 -13l12 1v-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.5 t-50 -9.5t-39 -14q3 -19 24.5 -46t21.5 -34q0 -11 -26 -30zM1061 -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 11zM822 568l48 12l109 -177l-73 -48zM1323 51q3 -15 3 -16q0 -7 -17.5 -14.5t-46 -13 t-54 -9.5t-53.5 -7.5t-32 -4.5l-7 43q21 2 60.5 8.5t72 10t60.5 3.5h14zM866 679l-96 -20l-6 17q10 1 32.5 7t34.5 6q19 0 35 -10zM1061 45h31l10 -83l-41 -12v95zM1950 1535v1v-1zM1950 1535l-1 -5l-2 -2l1 3zM1950 1535l1 1z" /> -<glyph unicode="" d="M1167 -50q-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 -16t7.5 -20q34 -32 87.5 -46t102.5 -12.5t99 4.5q41 4 84.5 20.5t65 30t28.5 20.5q12 12 7 29zM1128 65q-19 47 -39 61q-23 15 -76 15q-47 0 -71 -10 q-29 -12 -78 -56q-26 -24 -12 -44q9 -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.5t23 -14.5t13.5 -22q10 -17 12.5 -20t12.5 1q23 12 14 34zM1483 346q0 22 -5 44.5t-16.5 45t-34 36.5t-52.5 14 q-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.5q-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 106zM1536 506q0 -164 -62 -304.5t-166 -236t-242.5 -149.5t-290.5 -54t-293 57.5t-247.5 157t-170.5 241.5t-64 302q0 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 44 q36 28 58 72.5t30 125.5q129 -155 186 -193q44 -29 130 -68t129 -66q21 -13 39 -25t60.5 -46.5t76 -70.5t75 -95t69 -122t47 -148.5t19.5 -177.5z" /> -<glyph unicode="" d="M1070 463l-160 -160l-151 -152l-30 -30q-65 -64 -151.5 -87t-171.5 -2q-16 -70 -72 -115t-129 -45q-85 0 -145 60.5t-60 145.5q0 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 160z M729 1145l12 -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.5q-70 15 -115 71t-45 129q0 85 60 145.5t145 60.5q76 0 133.5 -49t69.5 -123q84 20 169.5 -3.5 t149.5 -87.5zM1536 78q0 -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 30l-152 152l-160 160l152 152l160 -160l152 -152l29 -30q64 -64 87.5 -150.5t2.5 -171.5 q76 -11 126.5 -68.5t50.5 -134.5zM1534 1202q0 -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 -152l-160 -160l-152 152l161 160l152 152l29 30q67 67 159 89.5t178 -3.5q11 75 68.5 126 t135.5 51q85 0 145 -60.5t60 -145.5z" /> -<glyph unicode="" d="M654 458q-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 -110q-4 -2 -19.5 -4t-18.5 0q6 4 82 92q21 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 -5 q-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 8t14.5 5.5t6 -0.5q2 -12 -1 -33q0 -2 -12.5 -27t-26.5 -53.5t-17 -33.5q-25 -50 -77 -131l64 -28 q12 -6 74.5 -32t67.5 -28q4 -1 10.5 -25.5t4.5 -30.5zM449 944q3 -15 -4 -28q-12 -23 -50 -38q-30 -12 -60 -12q-26 3 -49 26q-14 15 -18 41l1 3q3 -3 19.5 -5t26.5 0t58 16q36 12 55 14q17 0 21 -17zM1147 815l63 -227l-139 42zM39 15l694 232v1032l-694 -233v-1031z M1280 332l102 -31l-181 657l-100 31l-216 -536l102 -31l45 110l211 -65zM777 1294l573 -184v380zM1088 -29l158 -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 16q0 8 5 13.5t13 5.5q4 0 18 -7.5t30.5 -16.5t20.5 -11 q73 -37 159.5 -61.5t157.5 -24.5q95 0 167 14.5t157 50.5q15 7 30.5 15.5t34 19t28.5 16.5zM1536 1050v-1079l-774 246q-14 -6 -375 -127.5t-368 -121.5q-13 0 -18 13q0 1 -1 3v1078q3 9 4 10q5 6 20 11q106 35 149 50v384l558 -198q2 0 160.5 55t316 108.5t161.5 53.5 q20 0 20 -21v-418z" /> -<glyph unicode="" horiz-adv-x="1792" d="M288 1152q66 0 113 -47t47 -113v-1088q0 -66 -47 -113t-113 -47h-128q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h128zM1664 989q58 -34 93 -93t35 -128v-768q0 -106 -75 -181t-181 -75h-864q-66 0 -113 47t-47 113v1536q0 40 28 68t68 28h672q40 0 88 -20t76 -48 l152 -152q28 -28 48 -76t20 -88v-163zM928 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM928 512v128q0 14 -9 23 t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1184 256v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128 q14 0 23 9t9 23zM1184 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 0v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 256v128q0 14 -9 23t-23 9h-128 q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1440 512v128q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h128q14 0 23 9t9 23zM1536 896v256h-160q-40 0 -68 28t-28 68v160h-640v-512h896z" /> -<glyph unicode="" d="M1344 1536q26 0 45 -19t19 -45v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280zM512 1248v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 992v-64q0 -14 9 -23t23 -9h64q14 0 23 9 t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 736v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM512 480v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23zM384 160v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM384 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM384 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 -96v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9 t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM896 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 928v64 q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM896 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 160v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64 q14 0 23 9t9 23zM1152 416v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 672v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 928v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9 t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1152 1184v64q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h64q14 0 23 9t9 23z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1188 988l-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 68t28 68t68 28t68 -28l228 -228h368l228 228q28 28 68 28t68 -28t28 -68t-28 -68zM864 1152q0 -93 -65.5 -158.5 t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" horiz-adv-x="1664" d="M780 1064q0 -60 -19 -113.5t-63 -92.5t-105 -39q-76 0 -138 57.5t-92 135.5t-30 151q0 60 19 113.5t63 92.5t105 39q77 0 138.5 -57.5t91.5 -135t30 -151.5zM438 581q0 -80 -42 -139t-119 -59q-76 0 -141.5 55.5t-100.5 133.5t-35 152q0 80 42 139.5t119 59.5 q76 0 141.5 -55.5t100.5 -134t35 -152.5zM832 608q118 0 255 -97.5t229 -237t92 -254.5q0 -46 -17 -76.5t-48.5 -45t-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 146q0 86 56 191.5t139.5 192.5t187.5 146t193 59zM1071 819 q-61 0 -105 39t-63 92.5t-19 113.5q0 74 30 151.5t91.5 135t138.5 57.5q61 0 105 -39t63 -92.5t19 -113.5q0 -73 -30 -151t-92 -135.5t-138 -57.5zM1503 923q77 0 119 -59.5t42 -139.5q0 -74 -35 -152t-100.5 -133.5t-141.5 -55.5q-77 0 -119 59t-42 139q0 74 35 152.5 t100.5 134t141.5 55.5z" /> -<glyph unicode="" horiz-adv-x="768" d="M704 1008q0 -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.5q0 128 42.5 249.5t117.5 200t160 78.5t160 -78.5t117.5 -200t42.5 -249.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 -93l640 349v636l-640 -233v-752zM832 772l698 254l-698 254l-698 -254zM1664 1024v-768q0 -35 -18 -65t-49 -47l-704 -384q-28 -16 -61 -16t-61 16l-704 384q-31 17 -49 47t-18 65v768q0 40 23 73t61 47l704 256q22 8 44 8t44 -8l704 -256q38 -14 61 -47t23 -73z " /> -<glyph unicode="" horiz-adv-x="2304" d="M640 -96l384 192v314l-384 -164v-342zM576 358l404 173l-404 173l-404 -173zM1664 -96l384 192v314l-384 -164v-342zM1600 358l404 173l-404 173l-404 -173zM1152 651l384 165v266l-384 -164v-267zM1088 1030l441 189l-441 189l-441 -189zM2176 512v-416q0 -36 -19 -67 t-52 -47l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-5 2 -7 4q-2 -2 -7 -4l-448 -224q-25 -14 -57 -14t-57 14l-448 224q-33 16 -52 47t-19 67v416q0 38 21.5 70t56.5 48l434 186v400q0 38 21.5 70t56.5 48l448 192q23 10 50 10t50 -10l448 -192q35 -16 56.5 -48t21.5 -70 v-400l434 -186q36 -16 57 -48t21 -70z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1848 1197h-511v-124h511v124zM1596 771q-90 0 -146 -52.5t-62 -142.5h408q-18 195 -200 195zM1612 186q63 0 122 32t76 87h221q-100 -307 -427 -307q-214 0 -340.5 132t-126.5 347q0 208 130.5 345.5t336.5 137.5q138 0 240.5 -68t153 -179t50.5 -248q0 -17 -2 -47h-658 q0 -111 57.5 -171.5t166.5 -60.5zM277 236h296q205 0 205 167q0 180 -199 180h-302v-347zM277 773h281q78 0 123.5 36.5t45.5 113.5q0 144 -190 144h-260v-294zM0 1282h594q87 0 155 -14t126.5 -47.5t90 -96.5t31.5 -154q0 -181 -172 -263q114 -32 172 -115t58 -204 q0 -75 -24.5 -136.5t-66 -103.5t-98.5 -71t-121 -42t-134 -13h-611v1260z" /> -<glyph unicode="" d="M1248 1408q119 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.5v960q0 119 84.5 203.5t203.5 84.5h960zM499 1041h-371v-787h382q117 0 197 57.5t80 170.5q0 158 -143 200q107 52 107 164q0 57 -19.5 96.5 t-56.5 60.5t-79 29.5t-97 8.5zM477 723h-176v184h163q119 0 119 -90q0 -94 -106 -94zM486 388h-185v217h189q124 0 124 -113q0 -104 -128 -104zM1136 356q-68 0 -104 38t-36 107h411q1 10 1 30q0 132 -74.5 220.5t-203.5 88.5q-128 0 -210 -86t-82 -216q0 -135 79 -217 t213 -82q205 0 267 191h-138q-11 -34 -47.5 -54t-75.5 -20zM1126 722q113 0 124 -122h-254q4 56 39 89t91 33zM964 988h319v-77h-319v77z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1582 954q0 -101 -71.5 -172.5t-172.5 -71.5t-172.5 71.5t-71.5 172.5t71.5 172.5t172.5 71.5t172.5 -71.5t71.5 -172.5zM812 212q0 104 -73 177t-177 73q-27 0 -54 -6l104 -42q77 -31 109.5 -106.5t1.5 -151.5q-31 -77 -107 -109t-152 -1q-21 8 -62 24.5t-61 24.5 q32 -60 91 -96.5t130 -36.5q104 0 177 73t73 177zM1642 953q0 126 -89.5 215.5t-215.5 89.5q-127 0 -216.5 -89.5t-89.5 -215.5q0 -127 89.5 -216t216.5 -89q126 0 215.5 89t89.5 216zM1792 953q0 -189 -133.5 -322t-321.5 -133l-437 -319q-12 -129 -109 -218t-229 -89 q-121 0 -214 76t-118 192l-230 92v429l389 -157q79 48 173 48q13 0 35 -2l284 407q2 187 135.5 319t320.5 132q188 0 321.5 -133.5t133.5 -321.5z" /> -<glyph unicode="" d="M1242 889q0 80 -57 136.5t-137 56.5t-136.5 -57t-56.5 -136q0 -80 56.5 -136.5t136.5 -56.5t137 56.5t57 136.5zM632 301q0 -83 -58 -140.5t-140 -57.5q-56 0 -103 29t-72 77q52 -20 98 -40q60 -24 120 1.5t85 86.5q24 60 -1.5 120t-86.5 84l-82 33q22 5 42 5 q82 0 140 -57.5t58 -140.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v153l172 -69q20 -92 93.5 -152t168.5 -60q104 0 181 70t87 173l345 252q150 0 255.5 105.5t105.5 254.5q0 150 -105.5 255.5t-255.5 105.5 q-148 0 -253 -104.5t-107 -252.5l-225 -322q-9 1 -28 1q-75 0 -137 -37l-297 119v468q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5zM1289 887q0 -100 -71 -170.5t-171 -70.5t-170.5 70.5t-70.5 170.5t70.5 171t170.5 71q101 0 171.5 -70.5t70.5 -171.5z " /> -<glyph unicode="" horiz-adv-x="1792" d="M836 367l-15 -368l-2 -22l-420 29q-36 3 -67 31.5t-47 65.5q-11 27 -14.5 55t4 65t12 55t21.5 64t19 53q78 -12 509 -28zM449 953l180 -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 188 l-140 86zM1680 436l-188 -359q-12 -29 -36.5 -46.5t-43.5 -20.5l-18 -4q-71 -7 -219 -12l8 -164l-230 367l211 362l7 -173q170 -16 283 -5t170 33zM895 1360q-47 -63 -265 -435l-317 187l-19 12l225 356q20 31 60 45t80 10q24 -2 48.5 -12t42 -21t41.5 -33t36 -34.5 t36 -39.5t32 -35zM1550 1053l212 -363q18 -37 12.5 -76t-27.5 -74q-13 -20 -33 -37t-38 -28t-48.5 -22t-47 -16t-51.5 -14t-46 -12q-34 72 -265 436l313 195zM1407 1279l142 83l-220 -373l-419 20l151 86q-34 89 -75 166t-75.5 123.5t-64.5 80t-47 46.5l-17 13l405 -1 q31 3 58 -10.5t39 -28.5l11 -15q39 -61 112 -190z" /> -<glyph unicode="" horiz-adv-x="2048" d="M480 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM516 768h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5zM1888 448q0 66 -47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47t113 47t47 113zM2048 544v-384 q0 -14 -9 -23t-23 -9h-96v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-1024v-128q0 -80 -56 -136t-136 -56t-136 56t-56 136v128h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5t179 63.5h768q98 0 179 -63.5t104 -157.5 l105 -419h28q93 0 158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1824 640q93 0 158.5 -65.5t65.5 -158.5v-384q0 -14 -9 -23t-23 -9h-96v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-1024v-64q0 -80 -56 -136t-136 -56t-136 56t-56 136v64h-96q-14 0 -23 9t-9 23v384q0 93 65.5 158.5t158.5 65.5h28l105 419q23 94 104 157.5 t179 63.5h128v224q0 14 9 23t23 9h448q14 0 23 -9t9 -23v-224h128q98 0 179 -63.5t104 -157.5l105 -419h28zM320 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM516 640h1016l-89 357q-2 8 -14 17.5t-21 9.5h-768q-9 0 -21 -9.5t-14 -17.5z M1728 160q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47z" /> -<glyph unicode="" d="M1504 64q0 -26 -19 -45t-45 -19h-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 45t19 45l402 403h-229q-26 0 -45 19t-19 45t19 45l402 403h-197q-26 0 -45 19t-19 45t19 45l384 384 q19 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 -45z" /> -<glyph unicode="" d="M1127 326q0 32 -30 51q-193 115 -447 115q-133 0 -287 -34q-42 -9 -42 -52q0 -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.5zM1223 541q0 40 -35 61q-237 141 -548 141q-153 0 -303 -42q-48 -13 -48 -64 q0 -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.5zM1331 789q0 47 -40 70q-126 73 -293 110.5t-343 37.5q-204 0 -364 -47q-23 -7 -38.5 -25.5t-15.5 -48.5q0 -31 20.5 -52t51.5 -21q11 0 40 8q133 37 307 37 q159 0 309.5 -34t253.5 -95q21 -12 40 -12q29 0 50.5 20.5t21.5 51.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1024" d="M1024 1233l-303 -582l24 -31h279v-415h-507l-44 -30l-142 -273l-30 -30h-301v303l303 583l-24 30h-279v415h507l44 30l142 273l30 30h301v-303z" /> -<glyph unicode="" horiz-adv-x="2304" d="M784 164l16 241l-16 523q-1 10 -7.5 17t-16.5 7q-9 0 -16 -7t-7 -17l-14 -523l14 -241q1 -10 7.5 -16.5t15.5 -6.5q22 0 24 23zM1080 193l11 211l-12 586q0 16 -13 24q-8 5 -16 5t-16 -5q-13 -8 -13 -24l-1 -6l-10 -579q0 -1 11 -236v-1q0 -10 6 -17q9 -11 23 -11 q11 0 20 9q9 7 9 20zM35 533l20 -128l-20 -126q-2 -9 -9 -9t-9 9l-17 126l17 128q2 9 9 9t9 -9zM121 612l26 -207l-26 -203q-2 -9 -10 -9q-9 0 -9 10l-23 202l23 207q0 9 9 9q8 0 10 -9zM401 159zM213 650l25 -245l-25 -237q0 -11 -11 -11q-10 0 -12 11l-21 237l21 245 q2 12 12 12q11 0 11 -12zM307 657l23 -252l-23 -244q-2 -13 -14 -13q-13 0 -13 13l-21 244l21 252q0 13 13 13q12 0 14 -13zM401 639l21 -234l-21 -246q-2 -16 -16 -16q-6 0 -10.5 4.5t-4.5 11.5l-20 246l20 234q0 6 4.5 10.5t10.5 4.5q14 0 16 -15zM784 164zM495 785 l21 -380l-21 -246q0 -7 -5 -12.5t-12 -5.5q-16 0 -18 18l-18 246l18 380q2 18 18 18q7 0 12 -5.5t5 -12.5zM589 871l19 -468l-19 -244q0 -8 -5.5 -13.5t-13.5 -5.5q-18 0 -20 19l-16 244l16 468q2 19 20 19q8 0 13.5 -5.5t5.5 -13.5zM687 911l18 -506l-18 -242 q-2 -21 -22 -21q-19 0 -21 21l-16 242l16 506q0 9 6.5 15.5t14.5 6.5q9 0 15 -6.5t7 -15.5zM1079 169v0v0zM881 915l15 -510l-15 -239q0 -10 -7.5 -17.5t-17.5 -7.5t-17 7t-8 18l-14 239l14 510q0 11 7.5 18t17.5 7t17.5 -7t7.5 -18zM980 896l14 -492l-14 -236q0 -11 -8 -19 t-19 -8t-19 8t-9 19l-12 236l12 492q1 12 9 20t19 8t18.5 -8t8.5 -20zM1192 404l-14 -231v0q0 -13 -9 -22t-22 -9t-22 9t-10 22l-6 114l-6 117l12 636v3q2 15 12 24q9 7 20 7q8 0 15 -5q14 -8 16 -26zM2304 423q0 -117 -83 -199.5t-200 -82.5h-786q-13 2 -22 11t-9 22v899 q0 23 28 33q85 34 181 34q195 0 338 -131.5t160 -323.5q53 22 110 22q117 0 200 -83t83 -201z" /> -<glyph unicode="" d="M768 768q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 0q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127 t443 -43zM768 384q237 0 443 43t325 127v-170q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5t-103 128v170q119 -84 325 -127t443 -43zM768 1536q208 0 385 -34.5t280 -93.5t103 -128v-128q0 -69 -103 -128t-280 -93.5t-385 -34.5t-385 34.5t-280 93.5 t-103 128v128q0 69 103 128t280 93.5t385 34.5z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M894 465q33 -26 84 -56q59 7 117 7q147 0 177 -49q16 -22 2 -52q0 -1 -1 -2l-2 -2v-1q-6 -38 -71 -38q-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 36q9 40 56 91.5t132 96.5q14 9 23 -6q2 -2 2 -4q52 85 107 197 q68 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 -238zM318 54q52 24 137 158q-51 -40 -87.5 -84t-49.5 -74zM716 974q-15 -42 -2 -132q1 7 7 44q0 3 7 43q1 4 4 8 q-1 1 -1 2t-0.5 1.5t-0.5 1.5q-1 22 -13 36q0 -1 -1 -2v-2zM592 313q135 54 284 81q-2 1 -13 9.5t-16 13.5q-76 67 -127 176q-27 -86 -83 -197q-30 -56 -45 -83zM1238 329q-24 24 -140 24q76 -28 124 -28q14 0 18 1q0 1 -2 3z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M233 768v-107h70l164 -661h159l128 485q7 20 10 46q2 16 2 24h4l3 -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 21 q-2 26 -7 46l-99 438h90v107h-300z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M429 106v-106h281v106h-75l103 161q5 7 10 16.5t7.5 13.5t3.5 4h2q1 -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 159h76v107 h-290v-107h68l189 -272l-194 -283h-68z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M416 106v-106h327v106h-93v167h137q76 0 118 15q67 23 106.5 87t39.5 146q0 81 -37 141t-100 87q-48 19 -130 19h-368v-107h92v-555h-92zM769 386h-119v268h120q52 0 83 -18q56 -33 56 -115q0 -89 -62 -120q-31 -15 -78 -15z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M1280 320v-320h-1024v192l192 192l128 -128l384 384zM448 512q-80 0 -136 56t-56 136t56 136t136 56t136 -56t56 -136t-56 -136t-136 -56z" /> -<glyph unicode="" d="M640 1152v128h-128v-128h128zM768 1024v128h-128v-128h128zM640 896v128h-128v-128h128zM768 768v128h-128v-128h128zM1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400 v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-128v-128h-128v128h-512v-1536h1280zM781 593l107 -349q8 -27 8 -52q0 -83 -72.5 -137.5t-183.5 -54.5t-183.5 54.5t-72.5 137.5q0 25 8 52q21 63 120 396v128h128v-128h79 q22 0 39 -13t23 -34zM640 128q53 0 90.5 19t37.5 45t-37.5 45t-90.5 19t-90.5 -19t-37.5 -45t37.5 -45t90.5 -19z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M620 686q20 -8 20 -30v-544q0 -22 -20 -30q-8 -2 -12 -2q-12 0 -23 9l-166 167h-131q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h131l166 167q16 15 35 7zM1037 -3q31 0 50 24q129 159 129 363t-129 363q-16 21 -43 24t-47 -14q-21 -17 -23.5 -43.5t14.5 -47.5 q100 -123 100 -282t-100 -282q-17 -21 -14.5 -47.5t23.5 -42.5q18 -15 40 -15zM826 145q27 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.5t20 -44.5q20 -17 44 -17z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M768 768q52 0 90 -38t38 -90v-384q0 -52 -38 -90t-90 -38h-384q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h384zM1260 766q20 -8 20 -30v-576q0 -22 -20 -30q-8 -2 -12 -2q-14 0 -23 9l-265 266v90l265 266q9 9 23 9q4 0 12 -2z" /> -<glyph unicode="" d="M1468 1156q28 -28 48 -76t20 -88v-1152q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1600q0 40 28 68t68 28h896q40 0 88 -20t76 -48zM1024 1400v-376h376q-10 29 -22 41l-313 313q-12 12 -41 22zM1408 -128v1024h-416q-40 0 -68 28t-28 68v416h-768v-1536h1280z M480 768q8 11 21 12.5t24 -6.5l51 -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.5l-226 301q-14 19 0 38zM1282 467q14 -19 0 -38l-226 -301q-8 -11 -21 -12.5t-24 6.5l-51 38q-11 8 -12.5 21t6.5 24l182 243 l-182 243q-8 11 -6.5 24t12.5 21l51 38q11 8 24 6.5t21 -12.5zM662 6q-13 2 -20.5 13t-5.5 24l138 831q2 13 13 20.5t24 5.5l63 -10q13 -2 20.5 -13t5.5 -24l-138 -831q-2 -13 -13 -20.5t-24 -5.5z" /> -<glyph unicode="" d="M1497 709v-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 390h283q26 -218 70 -398.5t104.5 -317t121.5 -235.5t140 -195q169 169 287 406 q-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 132t-79 45q-53 0 -85 -49.5t-32 -140.5q0 -186 105 -293.5t267 -107.5q62 0 121 14z" /> -<glyph unicode="" horiz-adv-x="1792" d="M216 367l603 -402v359l-334 223zM154 511l193 129l-193 129v-258zM973 -35l603 402l-269 180l-334 -223v-359zM896 458l272 182l-272 182l-272 -182zM485 733l334 223v359l-603 -402zM1445 640l193 -129v258zM1307 733l269 180l-603 402v-359zM1792 913v-546 q0 -41 -34 -64l-819 -546q-21 -13 -43 -13t-43 13l-819 546q-34 23 -34 64v546q0 41 34 64l819 546q21 13 43 13t43 -13l819 -546q34 -23 34 -64z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1800 764q111 -46 179.5 -145.5t68.5 -221.5q0 -164 -118 -280.5t-285 -116.5q-4 0 -11.5 0.5t-10.5 0.5h-1209h-1h-2h-5q-170 10 -288 125.5t-118 280.5q0 110 55 203t147 147q-12 39 -12 82q0 115 82 196t199 81q95 0 172 -58q75 154 222.5 248t326.5 94 q166 0 306 -80.5t221.5 -218.5t81.5 -301q0 -6 -0.5 -18t-0.5 -18zM468 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 -55 t121.5 -21q121 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.5 t-85 -189.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM896 1408q-190 0 -361 -90l194 -194q82 28 167 28t167 -28l194 194q-171 90 -361 90zM218 279l194 194 q-28 82 -28 167t28 167l-194 194q-90 -171 -90 -361t90 -361zM896 -128q190 0 361 90l-194 194q-82 -28 -167 -28t-167 28l-194 -194q171 -90 361 -90zM896 256q159 0 271.5 112.5t112.5 271.5t-112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5 t271.5 -112.5zM1380 473l194 -194q90 171 90 361t-90 361l-194 -194q28 -82 28 -167t-28 -167z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348q0 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.5 q0 230 -145.5 406t-366.5 221v260q215 -31 390.5 -155.5t276.5 -317t101 -414.5z" /> -<glyph unicode="" 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="" horiz-adv-x="1792" d="M874 -102v-66q-208 6 -385 109.5t-283 275.5l58 34q29 -49 73 -99l65 57q148 -168 368 -212l-17 -86q65 -12 121 -13zM276 428l-83 -28q22 -60 49 -112l-57 -33q-98 180 -98 385t98 385l57 -33q-30 -56 -49 -112l82 -28q-35 -100 -35 -212q0 -109 36 -212zM1528 251 l58 -34q-106 -172 -283 -275.5t-385 -109.5v66q56 1 121 13l-17 86q220 44 368 212l65 -57q44 50 73 99zM1377 805l-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 -162 q-67 77 -98 169l232 80q-14 42 -14 85t14 85l-233 80q33 93 99 169l185 -162q59 68 147 86l-48 240q44 10 98 10t98 -10l-48 -240q88 -18 147 -86l185 162q66 -76 99 -169zM874 1448v-66q-65 -2 -121 -13l17 -86q-220 -42 -368 -211l-65 56q-38 -42 -73 -98l-57 33 q106 172 282 275.5t385 109.5zM1705 640q0 -205 -98 -385l-57 33q27 52 49 112l-83 28q36 103 36 212q0 112 -35 212l82 28q-19 56 -49 112l57 33q98 -180 98 -385zM1585 1063l-57 -33q-35 56 -73 98l-65 -56q-148 169 -368 211l17 86q-56 11 -121 13v66q209 -6 385 -109.5 t282 -275.5zM1748 640q0 173 -67.5 331t-181.5 272t-272 181.5t-331 67.5t-331 -67.5t-272 -181.5t-181.5 -272t-67.5 -331t67.5 -331t181.5 -272t272 -181.5t331 -67.5t331 67.5t272 181.5t181.5 272t67.5 331zM1792 640q0 -182 -71 -348t-191 -286t-286 -191t-348 -71 t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> -<glyph unicode="" d="M582 228q0 -66 -93 -66q-107 0 -107 63q0 64 98 64q102 0 102 -61zM546 694q0 -85 -74 -85q-77 0 -77 84q0 90 77 90q36 0 55 -25.5t19 -63.5zM712 769v125q-78 -29 -135 -29q-50 29 -110 29q-86 0 -145 -57t-59 -143q0 -50 29.5 -102t73.5 -67v-3q-38 -17 -38 -85 q0 -53 41 -77v-3q-113 -37 -113 -139q0 -45 20 -78.5t54 -51t72 -25.5t81 -8q224 0 224 188q0 67 -48 99t-126 46q-27 5 -51.5 20.5t-24.5 39.5q0 44 49 52q77 15 122 70t45 134q0 24 -10 52q37 9 49 13zM771 350h137q-2 27 -2 82v387q0 46 2 69h-137q3 -23 3 -71v-392 q0 -50 -3 -75zM1280 366v121q-30 -21 -68 -21q-53 0 -53 82v225h52q9 0 26.5 -1t26.5 -1v117h-105q0 82 3 102h-140q4 -24 4 -55v-47h-60v-117q36 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 24zM924 1072 q0 36 -24 63.5t-60 27.5t-60.5 -27t-24.5 -64q0 -36 25 -62.5t60 -26.5t59.5 27t24.5 62zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M595 22q0 100 -165 100q-158 0 -158 -104q0 -101 172 -101q151 0 151 105zM536 777q0 61 -30 102t-89 41q-124 0 -124 -145q0 -135 124 -135q119 0 119 137zM805 1101v-202q-36 -12 -79 -22q16 -43 16 -84q0 -127 -73 -216.5t-197 -112.5q-40 -8 -59.5 -27t-19.5 -58 q0 -31 22.5 -51.5t58 -32t78.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.5q0 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 -47 q98 0 218 47zM1123 220h-222q4 45 4 134v609q0 94 -4 128h222q-4 -33 -4 -124v-613q0 -89 4 -134zM1724 442v-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 -6v190h96v76q0 54 -6 89h227q-6 -41 -6 -165h171 v-190q-15 0 -43.5 2t-42.5 2h-85v-365q0 -131 87 -131q61 0 109 33zM1148 1389q0 -58 -39 -101.5t-96 -43.5q-58 0 -98 43.5t-40 101.5q0 59 39.5 103t98.5 44q58 0 96.5 -44.5t38.5 -102.5z" /> -<glyph unicode="" d="M825 547l343 588h-150q-21 -39 -63.5 -118.5t-68 -128.5t-59.5 -118.5t-60 -128.5h-3q-21 48 -44.5 97t-52 105.5t-46.5 92t-54 104.5t-49 95h-150l323 -589v-435h134v436zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960 q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M842 964q0 -80 -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.5t29.5 217t54 186t69 155.5t74 125q61 90 132 165q-16 35 -16 77q0 80 56.5 136.5t136.5 56.5 t136.5 -56.5t56.5 -136.5zM1223 953q0 -158 -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 153t-153 102t-186 38t-186 -38t-153 -102t-102 -153 t-38 -186q0 -114 52 -218q10 -20 3.5 -40t-25.5 -30t-39.5 -3t-30.5 26q-64 123 -64 265q0 119 46.5 227t124.5 186t186 124t226 46q158 0 292.5 -78t212.5 -212.5t78 -292.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M270 730q-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.5t3.5 -5t2 -3.5 q77 -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 9t-98 20 t-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 -20q-18 -41 -54.5 -74.5 t-77.5 -37.5h-1q-4 0 -6 4.5t-5 5.5q-23 54 -23 100q0 275 252 466z" /> -<glyph unicode="" horiz-adv-x="2048" d="M580 1075q0 41 -25 66t-66 25q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 66 24.5t25 65.5zM1323 568q0 28 -25.5 50t-65.5 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q40 0 65.5 22t25.5 51zM1087 1075q0 41 -24.5 66t-65.5 25 q-43 0 -76 -25.5t-33 -65.5q0 -39 33 -64.5t76 -25.5q41 0 65.5 24.5t24.5 65.5zM1722 568q0 28 -26 50t-65 22q-27 0 -49.5 -22.5t-22.5 -49.5q0 -28 22.5 -50.5t49.5 -22.5q39 0 65 22t26 51zM1456 965q-31 4 -70 4q-169 0 -311 -77t-223.5 -208.5t-81.5 -287.5 q0 -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 490q0 169 97.5 311t264 223.5t363.5 81.5q176 0 332.5 -66t262 -182.5t136.5 -260.5zM2048 404q0 -117 -68.5 -223.5t-185.5 -193.5l55 -181l-199 109 q-150 -37 -218 -37q-169 0 -311 70.5t-223.5 191.5t-81.5 264t81.5 264t223.5 191.5t311 70.5q161 0 303 -70.5t227.5 -192t85.5 -263.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1764 1525q33 -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 55q-2 40 32 59l1664 960q15 9 32 9q20 0 36 -11z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1764 1525q33 -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 55q-3 39 32 59l1664 960q35 21 68 -2zM1422 26l221 1323l-1434 -827l336 -137 l863 639l-478 -797z" /> -<glyph unicode="" d="M1536 640q0 -156 -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 -12q73 -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.5 t-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 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298zM896 928v-448q0 -14 -9 -23 t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5t-51 248.5t-136.5 204t-204 136.5t-248.5 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1682 -128q-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.5t45 -15 t20 -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 18q-15 10 -45 12t-53 2 t-41 14t-18 45q0 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 -22z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1278 1347v-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-108q-26 0 -43.5 18t-17.5 43v496q-147 12 -245 59q-126 58 -192 179 q-64 117 -64 259q0 166 88 286q88 118 209 159q111 37 417 37h479q25 0 43 -18t18 -43z" /> -<glyph unicode="" d="M352 128v-128h-352v128h352zM704 256q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM864 640v-128h-864v128h864zM224 1152v-128h-224v128h224zM1536 128v-128h-736v128h736zM576 1280q26 0 45 -19t19 -45v-256 q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1216 768q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h256zM1536 640v-128h-224v128h224zM1536 1152v-128h-864v128h864z" /> -<glyph unicode="" d="M1216 512q133 0 226.5 -93.5t93.5 -226.5t-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.5t93.5 226.5t226.5 93.5q126 0 218 -86l360 180q-2 22 -2 34q0 133 93.5 226.5t226.5 93.5 t226.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 86z" /> -<glyph unicode="" d="M1280 341q0 88 -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.5t62.5 -150.5 t150.5 -62.5q83 0 145 57l241 -120q-2 -16 -2 -23q0 -88 63 -150.5t151 -62.5t150.5 62.5t62.5 150.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M571 947q-10 25 -34 35t-49 0q-108 -44 -191 -127t-127 -191q-10 -25 0 -49t35 -34q13 -5 24 -5q42 0 60 40q34 84 98.5 148.5t148.5 98.5q25 11 35 35t0 49zM1513 1303l46 -46l-244 -243l68 -68q19 -19 19 -45.5t-19 -45.5l-64 -64q89 -161 89 -343q0 -143 -55.5 -273.5 t-150 -225t-225 -150t-273.5 -55.5t-273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5q182 0 343 -89l64 64q19 19 45.5 19t45.5 -19l68 -68zM1521 1359q-10 -10 -22 -10q-13 0 -23 10l-91 90q-9 10 -9 23t9 23q10 9 23 9t23 -9l90 -91 q10 -9 10 -22.5t-10 -22.5zM1751 1129q-11 -9 -23 -9t-23 9l-90 91q-10 9 -10 22.5t10 22.5q9 10 22.5 10t22.5 -10l91 -90q9 -10 9 -23t-9 -23zM1792 1312q0 -14 -9 -23t-23 -9h-96q-14 0 -23 9t-9 23t9 23t23 9h96q14 0 23 -9t9 -23zM1600 1504v-96q0 -14 -9 -23t-23 -9 t-23 9t-9 23v96q0 14 9 23t23 9t23 -9t9 -23zM1751 1449l-91 -90q-10 -10 -22 -10q-13 0 -23 10q-10 9 -10 22.5t10 22.5l90 91q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M609 720l287 208l287 -208l-109 -336h-355zM896 1536q182 0 348 -71t286 -191t191 -286t71 -348t-71 -348t-191 -286t-286 -191t-348 -71t-348 71t-286 191t-191 286t-71 348t71 348t191 286t286 191t348 71zM1515 186q149 203 149 454v3l-102 -89l-240 224l63 323 l134 -12q-150 206 -389 282l53 -124l-287 -159l-287 159l53 124q-239 -76 -389 -282l135 12l62 -323l-240 -224l-102 89v-3q0 -251 149 -454l30 132l326 -40l139 -298l-116 -69q117 -39 240 -39t240 39l-116 69l139 298l326 40z" /> -<glyph unicode="" horiz-adv-x="1792" d="M448 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM256 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM832 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM66 768q-28 0 -47 19t-19 46v129h514v-129q0 -27 -19 -46t-46 -19h-383zM1216 224v-192q0 -14 -9 -23t-23 -9h-192 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1600 224v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23 zM1408 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1016v-13h-514v10q0 104 -382 102q-382 -1 -382 -102v-10h-514v13q0 17 8.5 43t34 64t65.5 75.5t110.5 76t160 67.5t224 47.5t293.5 18.5t293 -18.5t224 -47.5 t160.5 -67.5t110.5 -76t65.5 -75.5t34 -64t8.5 -43zM1792 608v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 962v-129q0 -27 -19 -46t-46 -19h-384q-27 0 -46 19t-19 46v129h514z" /> -<glyph unicode="" horiz-adv-x="1792" d="M704 1216v-768q0 -26 -19 -45t-45 -19v-576q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v512l249 873q7 23 31 23h424zM1024 1216v-704h-256v704h256zM1792 320v-512q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v576q-26 0 -45 19t-19 45v768h424q24 0 31 -23z M736 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23zM1408 1504v-224h-352v224q0 14 9 23t23 9h288q14 0 23 -9t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1755 1083q37 -37 37 -90t-37 -91l-401 -400l150 -150l-160 -160q-163 -163 -389.5 -186.5t-411.5 100.5l-362 -362h-181v181l362 362q-124 185 -100.5 411.5t186.5 389.5l160 160l150 -150l400 401q38 37 91 37t90 -37t37 -90.5t-37 -90.5l-400 -401l234 -234l401 400 q38 37 91 37t90 -37z" /> -<glyph unicode="" horiz-adv-x="1792" d="M873 796q0 -83 -63.5 -142.5t-152.5 -59.5t-152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59t152.5 -59t63.5 -143zM1375 796q0 -83 -63 -142.5t-153 -59.5q-89 0 -152.5 59.5t-63.5 142.5q0 84 63.5 143t152.5 59q90 0 153 -59t63 -143zM1600 616v667q0 87 -32 123.5 t-111 36.5h-1112q-83 0 -112.5 -34t-29.5 -126v-673q43 -23 88.5 -40t81 -28t81 -18.5t71 -11t70 -4t58.5 -0.5t56.5 2t44.5 2q68 1 95 -27q6 -6 10 -9q26 -25 61 -51q7 91 118 87q5 0 36.5 -1.5t43 -2t45.5 -1t53 1t54.5 4.5t61 8.5t62 13.5t67 19.5t67.5 27t72 34.5z M1763 621q-121 -149 -372 -252q84 -285 -23 -465q-66 -113 -183 -148q-104 -32 -182 15q-86 51 -82 164l-1 326v1q-8 2 -24.5 6t-23.5 5l-1 -338q4 -114 -83 -164q-79 -47 -183 -15q-117 36 -182 150q-105 180 -22 463q-251 103 -372 252q-25 37 -4 63t60 -1q3 -2 11 -7 t11 -8v694q0 72 47 123t114 51h1257q67 0 114 -51t47 -123v-694l21 15q39 27 60 1t-4 -63z" /> -<glyph unicode="" horiz-adv-x="1792" d="M896 1102v-434h-145v434h145zM1294 1102v-434h-145v434h145zM1294 342l253 254v795h-1194v-1049h326v-217l217 217h398zM1692 1536v-1013l-434 -434h-326l-217 -217h-217v217h-398v1158l109 289h1483z" /> -<glyph unicode="" d="M773 217v-127q-1 -292 -6 -305q-12 -32 -51 -40q-54 -9 -181.5 38t-162.5 89q-13 15 -17 36q-1 12 4 26q4 10 34 47t181 216q1 0 60 70q15 19 39.5 24.5t49.5 -3.5q24 -10 37.5 -29t12.5 -42zM624 468q-3 -55 -52 -70l-120 -39q-275 -88 -292 -88q-35 2 -54 36 q-12 25 -17 75q-8 76 1 166.5t30 124.5t56 32q13 0 202 -77q70 -29 115 -47l84 -34q23 -9 35.5 -30.5t11.5 -48.5zM1450 171q-7 -54 -91.5 -161t-135.5 -127q-37 -14 -63 7q-14 10 -184 287l-47 77q-14 21 -11.5 46t19.5 46q35 43 83 26q1 -1 119 -40q203 -66 242 -79.5 t47 -20.5q28 -22 22 -61zM778 803q5 -102 -54 -122q-58 -17 -114 71l-378 598q-8 35 19 62q41 43 207.5 89.5t224.5 31.5q40 -10 49 -45q3 -18 22 -305.5t24 -379.5zM1440 695q3 -39 -26 -59q-15 -10 -329 -86q-67 -15 -91 -23l1 2q-23 -6 -46 4t-37 32q-30 47 0 87 q1 1 75 102q125 171 150 204t34 39q28 19 65 2q48 -23 123 -133.5t81 -167.5v-3z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1024 1024h-384v-384h384v384zM1152 384v-128h-640v128h640zM1152 1152v-640h-640v640h640zM1792 384v-128h-512v128h512zM1792 640v-128h-512v128h512zM1792 896v-128h-512v128h512zM1792 1152v-128h-512v128h512zM256 192v960h-128v-960q0 -26 19 -45t45 -19t45 19 t19 45zM1920 192v1088h-1536v-1088q0 -33 -11 -64h1483q26 0 45 19t19 45zM2048 1408v-1216q0 -80 -56 -136t-136 -56h-1664q-80 0 -136 56t-56 136v1088h256v128h1792z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1024 13q-20 0 -93 73.5t-73 93.5q0 32 62.5 54t103.5 22t103.5 -22t62.5 -54q0 -20 -73 -93.5t-93 -73.5zM1294 284q-2 0 -40 25t-101.5 50t-128.5 25t-128.5 -25t-101 -50t-40.5 -25q-18 0 -93.5 75t-75.5 93q0 13 10 23q78 77 196 121t233 44t233 -44t196 -121 q10 -10 10 -23q0 -18 -75.5 -93t-93.5 -75zM1567 556q-11 0 -23 8q-136 105 -252 154.5t-268 49.5q-85 0 -170.5 -22t-149 -53t-113.5 -62t-79 -53t-31 -22q-17 0 -92 75t-75 93q0 12 10 22q132 132 320 205t380 73t380 -73t320 -205q10 -10 10 -22q0 -18 -75 -93t-92 -75z M1838 827q-11 0 -22 9q-179 157 -371.5 236.5t-420.5 79.5t-420.5 -79.5t-371.5 -236.5q-11 -9 -22 -9q-17 0 -92.5 75t-75.5 93q0 13 10 23q187 186 445 288t527 102t527 -102t445 -288q10 -10 10 -23q0 -18 -75.5 -93t-92.5 -75z" /> -<glyph unicode="" horiz-adv-x="1792" d="M384 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 0q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5 t37.5 90.5zM384 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1152 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM768 768q0 53 -37.5 90.5t-90.5 37.5 t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1536 0v384q0 52 -38 90t-90 38t-90 -38t-38 -90v-384q0 -52 38 -90t90 -38t90 38t38 90zM1152 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5z M1536 1088v256q0 26 -19 45t-45 19h-1280q-26 0 -45 -19t-19 -45v-256q0 -26 19 -45t45 -19h1280q26 0 45 19t19 45zM1536 768q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1408v-1536q0 -52 -38 -90t-90 -38 h-1408q-52 0 -90 38t-38 90v1536q0 52 38 90t90 38h1408q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1112 1090q0 159 -237 159h-70q-32 0 -59.5 -21.5t-34.5 -52.5l-63 -276q-2 -5 -2 -16q0 -24 17 -39.5t41 -15.5h53q69 0 128.5 13t112.5 41t83.5 81.5t30.5 126.5zM1716 938q0 -265 -220 -428q-219 -161 -612 -161h-61q-32 0 -59 -21.5t-34 -52.5l-73 -316 q-8 -36 -40.5 -61.5t-69.5 -25.5h-213q-31 0 -53 20t-22 51q0 10 13 65h151q34 0 64 23.5t38 56.5l73 316q8 33 37.5 57t63.5 24h61q390 0 607 160t217 421q0 129 -51 207q183 -92 183 -335zM1533 1123q0 -264 -221 -428q-218 -161 -612 -161h-60q-32 0 -59.5 -22t-34.5 -53 l-73 -315q-8 -36 -40 -61.5t-69 -25.5h-214q-31 0 -52.5 19.5t-21.5 51.5q0 8 2 20l300 1301q8 36 40.5 61.5t69.5 25.5h444q68 0 125 -4t120.5 -15t113.5 -30t96.5 -50.5t77.5 -74t49.5 -103.5t18.5 -136z" /> -<glyph unicode="" horiz-adv-x="1792" d="M602 949q19 -61 31 -123.5t17 -141.5t-14 -159t-62 -145q-21 81 -67 157t-95.5 127t-99 90.5t-78.5 57.5t-33 19q-62 34 -81.5 100t14.5 128t101 81.5t129 -14.5q138 -83 238 -177zM927 1236q11 -25 20.5 -46t36.5 -100.5t42.5 -150.5t25.5 -179.5t0 -205.5t-47.5 -209.5 t-105.5 -208.5q-51 -72 -138 -72q-54 0 -98 31q-57 40 -69 109t28 127q60 85 81 195t13 199.5t-32 180.5t-39 128t-22 52q-31 63 -8.5 129.5t85.5 97.5q34 17 75 17q47 0 88.5 -25t63.5 -69zM1248 567q-17 -160 -72 -311q-17 131 -63 246q25 174 -5 361q-27 178 -94 342 q114 -90 212 -211q9 -37 15 -80q26 -179 7 -347zM1520 1440q9 -17 23.5 -49.5t43.5 -117.5t50.5 -178t34 -227.5t5 -269t-47 -300t-112.5 -323.5q-22 -48 -66 -75.5t-95 -27.5q-39 0 -74 16q-67 31 -92.5 100t4.5 136q58 126 90 257.5t37.5 239.5t-3.5 213.5t-26.5 180.5 t-38.5 138.5t-32.5 90t-15.5 32.5q-34 65 -11.5 135.5t87.5 104.5q37 20 81 20q49 0 91.5 -25.5t66.5 -70.5z" /> -<glyph unicode="" horiz-adv-x="2304" d="M1975 546h-138q14 37 66 179l3 9q4 10 10 26t9 26l12 -55zM531 611l-58 295q-11 54 -75 54h-268l-2 -13q311 -79 403 -336zM710 960l-162 -438l-17 89q-26 70 -85 129.5t-131 88.5l135 -510h175l261 641h-176zM849 318h166l104 642h-166zM1617 944q-69 27 -149 27 q-123 0 -201 -59t-79 -153q-1 -102 145 -174q48 -23 67 -41t19 -39q0 -30 -30 -46t-69 -16q-86 0 -156 33l-22 11l-23 -144q74 -34 185 -34q130 -1 208.5 59t80.5 160q0 106 -140 174q-49 25 -71 42t-22 38q0 22 24.5 38.5t70.5 16.5q70 1 124 -24l15 -8zM2042 960h-128 q-65 0 -87 -54l-246 -588h174l35 96h212q5 -22 20 -96h154zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="2304" d="M671 603h-13q-47 0 -47 -32q0 -22 20 -22q17 0 28 15t12 39zM1066 639h62v3q1 4 0.5 6.5t-1 7t-2 8t-4.5 6.5t-7.5 5t-11.5 2q-28 0 -36 -38zM1606 603h-12q-48 0 -48 -32q0 -22 20 -22q17 0 28 15t12 39zM1925 629q0 41 -30 41q-19 0 -31 -20t-12 -51q0 -42 28 -42 q20 0 32.5 20t12.5 52zM480 770h87l-44 -262h-56l32 201l-71 -201h-39l-4 200l-34 -200h-53l44 262h81l2 -163zM733 663q0 -6 -4 -42q-16 -101 -17 -113h-47l1 22q-20 -26 -58 -26q-23 0 -37.5 16t-14.5 42q0 39 26 60.5t73 21.5q14 0 23 -1q0 3 0.5 5.5t1 4.5t0.5 3 q0 20 -36 20q-29 0 -59 -10q0 4 7 48q38 11 67 11q74 0 74 -62zM889 721l-8 -49q-22 3 -41 3q-27 0 -27 -17q0 -8 4.5 -12t21.5 -11q40 -19 40 -60q0 -72 -87 -71q-34 0 -58 6q0 2 7 49q29 -8 51 -8q32 0 32 19q0 7 -4.5 11.5t-21.5 12.5q-43 20 -43 59q0 72 84 72 q30 0 50 -4zM977 721h28l-7 -52h-29q-2 -17 -6.5 -40.5t-7 -38.5t-2.5 -18q0 -16 19 -16q8 0 16 2l-8 -47q-21 -7 -40 -7q-43 0 -45 47q0 12 8 56q3 20 25 146h55zM1180 648q0 -23 -7 -52h-111q-3 -22 10 -33t38 -11q30 0 58 14l-9 -54q-30 -8 -57 -8q-95 0 -95 95 q0 55 27.5 90.5t69.5 35.5q35 0 55.5 -21t20.5 -56zM1319 722q-13 -23 -22 -62q-22 2 -31 -24t-25 -128h-56l3 14q22 130 29 199h51l-3 -33q14 21 25.5 29.5t28.5 4.5zM1506 763l-9 -57q-28 14 -50 14q-31 0 -51 -27.5t-20 -70.5q0 -30 13.5 -47t38.5 -17q21 0 48 13 l-10 -59q-28 -8 -50 -8q-45 0 -71.5 30.5t-26.5 82.5q0 70 35.5 114.5t91.5 44.5q26 0 61 -13zM1668 663q0 -18 -4 -42q-13 -79 -17 -113h-46l1 22q-20 -26 -59 -26q-23 0 -37 16t-14 42q0 39 25.5 60.5t72.5 21.5q15 0 23 -1q2 7 2 13q0 20 -36 20q-29 0 -59 -10q0 4 8 48 q38 11 67 11q73 0 73 -62zM1809 722q-14 -24 -21 -62q-23 2 -31.5 -23t-25.5 -129h-56l3 14q19 104 29 199h52q0 -11 -4 -33q15 21 26.5 29.5t27.5 4.5zM1950 770h56l-43 -262h-53l3 19q-23 -23 -52 -23q-31 0 -49.5 24t-18.5 64q0 53 27.5 92t64.5 39q31 0 53 -29z M2061 640q0 148 -72.5 273t-198 198t-273.5 73q-181 0 -328 -110q127 -116 171 -284h-50q-44 150 -158 253q-114 -103 -158 -253h-50q44 168 171 284q-147 110 -328 110q-148 0 -273.5 -73t-198 -198t-72.5 -273t72.5 -273t198 -198t273.5 -73q181 0 328 110 q-120 111 -165 264h50q46 -138 152 -233q106 95 152 233h50q-45 -153 -165 -264q147 -110 328 -110q148 0 273.5 73t198 198t72.5 273zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="2304" d="M313 759q0 -51 -36 -84q-29 -26 -89 -26h-17v220h17q61 0 89 -27q36 -31 36 -83zM2089 824q0 -52 -64 -52h-19v101h20q63 0 63 -49zM380 759q0 74 -50 120.5t-129 46.5h-95v-333h95q74 0 119 38q60 51 60 128zM410 593h65v333h-65v-333zM730 694q0 40 -20.5 62t-75.5 42 q-29 10 -39.5 19t-10.5 23q0 16 13.5 26.5t34.5 10.5q29 0 53 -27l34 44q-41 37 -98 37q-44 0 -74 -27.5t-30 -67.5q0 -35 18 -55.5t64 -36.5q37 -13 45 -19q19 -12 19 -34q0 -20 -14 -33.5t-36 -13.5q-48 0 -71 44l-42 -40q44 -64 115 -64q51 0 83 30.5t32 79.5zM1008 604 v77q-37 -37 -78 -37q-49 0 -80.5 32.5t-31.5 82.5q0 48 31.5 81.5t77.5 33.5q43 0 81 -38v77q-40 20 -80 20q-74 0 -125.5 -50.5t-51.5 -123.5t51 -123.5t125 -50.5q42 0 81 19zM2240 0v527q-65 -40 -144.5 -84t-237.5 -117t-329.5 -137.5t-417.5 -134.5t-504 -118h1569 q26 0 45 19t19 45zM1389 757q0 75 -53 128t-128 53t-128 -53t-53 -128t53 -128t128 -53t128 53t53 128zM1541 584l144 342h-71l-90 -224l-89 224h-71l142 -342h35zM1714 593h184v56h-119v90h115v56h-115v74h119v57h-184v-333zM2105 593h80l-105 140q76 16 76 94q0 47 -31 73 t-87 26h-97v-333h65v133h9zM2304 1274v-1268q0 -56 -38.5 -95t-93.5 -39h-2040q-55 0 -93.5 39t-38.5 95v1268q0 56 38.5 95t93.5 39h2040q55 0 93.5 -39t38.5 -95z" /> -<glyph unicode="" horiz-adv-x="2304" d="M119 854h89l-45 108zM740 328l74 79l-70 79h-163v-49h142v-55h-142v-54h159zM898 406l99 -110v217zM1186 453q0 33 -40 33h-84v-69h83q41 0 41 36zM1475 457q0 29 -42 29h-82v-61h81q43 0 43 32zM1197 923q0 29 -42 29h-82v-60h81q43 0 43 31zM1656 854h89l-44 108z M699 1009v-271h-66v212l-94 -212h-57l-94 212v-212h-132l-25 60h-135l-25 -60h-70l116 271h96l110 -257v257h106l85 -184l77 184h108zM1255 453q0 -20 -5.5 -35t-14 -25t-22.5 -16.5t-26 -10t-31.5 -4.5t-31.5 -1t-32.5 0.5t-29.5 0.5v-91h-126l-80 90l-83 -90h-256v271h260 l80 -89l82 89h207q109 0 109 -89zM964 794v-56h-217v271h217v-57h-152v-49h148v-55h-148v-54h152zM2304 235v-229q0 -55 -38.5 -94.5t-93.5 -39.5h-2040q-55 0 -93.5 39.5t-38.5 94.5v678h111l25 61h55l25 -61h218v46l19 -46h113l20 47v-47h541v99l10 1q10 0 10 -14v-86h279 v23q23 -12 55 -18t52.5 -6.5t63 0.5t51.5 1l25 61h56l25 -61h227v58l34 -58h182v378h-180v-44l-25 44h-185v-44l-23 44h-249q-69 0 -109 -22v22h-172v-22q-24 22 -73 22h-628l-43 -97l-43 97h-198v-44l-22 44h-169l-78 -179v391q0 55 38.5 94.5t93.5 39.5h2040 q55 0 93.5 -39.5t38.5 -94.5v-678h-120q-51 0 -81 -22v22h-177q-55 0 -78 -22v22h-316v-22q-31 22 -87 22h-209v-22q-23 22 -91 22h-234l-54 -58l-50 58h-349v-378h343l55 59l52 -59h211v89h21q59 0 90 13v-102h174v99h8q8 0 10 -2t2 -10v-87h529q57 0 88 24v-24h168 q60 0 95 17zM1546 469q0 -23 -12 -43t-34 -29q25 -9 34 -26t9 -46v-54h-65v45q0 33 -12 43.5t-46 10.5h-69v-99h-65v271h154q48 0 77 -15t29 -58zM1269 936q0 -24 -12.5 -44t-33.5 -29q26 -9 34.5 -25.5t8.5 -46.5v-53h-65q0 9 0.5 26.5t0 25t-3 18.5t-8.5 16t-17.5 8.5 t-29.5 3.5h-70v-98h-64v271l153 -1q49 0 78 -14.5t29 -57.5zM1798 327v-56h-216v271h216v-56h-151v-49h148v-55h-148v-54zM1372 1009v-271h-66v271h66zM2065 357q0 -86 -102 -86h-126v58h126q34 0 34 25q0 16 -17 21t-41.5 5t-49.5 3.5t-42 22.5t-17 55q0 39 26 60t66 21 h130v-57h-119q-36 0 -36 -25q0 -16 17.5 -20.5t42 -4t49 -2.5t42 -21.5t17.5 -54.5zM2304 407v-101q-24 -35 -88 -35h-125v58h125q33 0 33 25q0 13 -12.5 19t-31 5.5t-40 2t-40 8t-31 24t-12.5 48.5q0 39 26.5 60t66.5 21h129v-57h-118q-36 0 -36 -25q0 -20 29 -22t68.5 -5 t56.5 -26zM2139 1008v-270h-92l-122 203v-203h-132l-26 60h-134l-25 -60h-75q-129 0 -129 133q0 138 133 138h63v-59q-7 0 -28 1t-28.5 0.5t-23 -2t-21.5 -6.5t-14.5 -13.5t-11.5 -23t-3 -33.5q0 -38 13.5 -58t49.5 -20h29l92 213h97l109 -256v256h99l114 -188v188h66z" /> -<glyph unicode="" horiz-adv-x="2304" d="M322 689h-15q-19 0 -19 18q0 28 19 85q5 15 15 19.5t28 4.5q77 0 77 -49q0 -41 -30.5 -59.5t-74.5 -18.5zM664 528q-47 0 -47 29q0 62 123 62l3 -3q-5 -88 -79 -88zM1438 687h-15q-19 0 -19 19q0 28 19 85q5 15 14.5 19t28.5 4q77 0 77 -49q0 -41 -30.5 -59.5 t-74.5 -18.5zM1780 527q-47 0 -47 30q0 62 123 62l3 -3q-5 -89 -79 -89zM373 894h-128q-8 0 -14.5 -4t-8.5 -7.5t-7 -12.5q-3 -7 -45 -190t-42 -192q0 -7 5.5 -12.5t13.5 -5.5h62q25 0 32.5 34.5l15 69t32.5 34.5q47 0 87.5 7.5t80.5 24.5t63.5 52.5t23.5 84.5 q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM719 798q-38 0 -74 -6q-2 0 -8.5 -1t-9 -1.5l-7.5 -1.5t-7.5 -2t-6.5 -3t-6.5 -4t-5 -5t-4.5 -7t-4 -9q-9 -29 -9 -39t9 -10q5 0 21.5 5t19.5 6q30 8 58 8q74 0 74 -36q0 -11 -10 -14q-8 -2 -18 -3t-21.5 -1.5t-17.5 -1.5 q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5q0 -38 26 -59.5t64 -21.5q24 0 45.5 6.5t33 13t38.5 23.5q-3 -7 -3 -15t5.5 -13.5t12.5 -5.5h56q1 1 7 3.5t7.5 3.5t5 3.5t5 5.5t2.5 8l45 194q4 13 4 30q0 81 -145 81zM1247 793h-74q-22 0 -39 -23q-5 -7 -29.5 -51 t-46.5 -81.5t-26 -38.5l-5 4q0 77 -27 166q-1 5 -3.5 8.5t-6 6.5t-6.5 5t-8.5 3t-8.5 1.5t-9.5 1t-9 0.5h-10h-8.5q-38 0 -38 -21l1 -5q5 -53 25 -151t25 -143q2 -16 2 -24q0 -19 -30.5 -61.5t-30.5 -58.5q0 -13 40 -13q61 0 76 25l245 415q10 20 10 26q0 9 -8 9zM1489 892 h-129q-18 0 -29 -23q-6 -13 -46.5 -191.5t-40.5 -190.5q0 -20 43 -20h7.5h9h9t9.5 1t8.5 2t8.5 3t6.5 4.5t5.5 6t3 8.5l21 91q2 10 10.5 17t19.5 7q47 0 87.5 7t80.5 24.5t63.5 52.5t23.5 84q0 36 -14.5 61t-41 36.5t-53.5 15.5t-62 4zM1835 798q-26 0 -74 -6 q-38 -6 -48 -16q-7 -8 -11 -19q-8 -24 -8 -39q0 -10 8 -10q1 0 41 12q30 8 58 8q74 0 74 -36q0 -12 -10 -14q-4 -1 -57 -7q-38 -4 -64.5 -10t-56.5 -19.5t-45.5 -39t-15.5 -62.5t26 -58.5t64 -21.5q24 0 45 6t34 13t38 24q-3 -15 -3 -16q0 -5 2 -8.5t6.5 -5.5t8 -3.5 t10.5 -2t9.5 -0.5h9.5h8q42 0 48 25l45 194q3 15 3 31q0 81 -145 81zM2157 889h-55q-25 0 -33 -40q-10 -44 -36.5 -167t-42.5 -190v-5q0 -16 16 -18h1h57q10 0 18.5 6.5t10.5 16.5l83 374h-1l1 5q0 7 -5.5 12.5t-13.5 5.5zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048 q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="2304" d="M1597 633q0 -69 -21 -106q-19 -35 -52 -35q-23 0 -41 9v224q29 30 57 30q57 0 57 -122zM2035 669h-110q6 98 56 98q51 0 54 -98zM476 534q0 59 -33 91.5t-101 57.5q-36 13 -52 24t-16 25q0 26 38 26q58 0 124 -33l18 112q-67 32 -149 32q-77 0 -123 -38q-48 -39 -48 -109 q0 -58 32.5 -90.5t99.5 -56.5q39 -14 54.5 -25.5t15.5 -27.5q0 -31 -48 -31q-29 0 -70 12.5t-72 30.5l-18 -113q72 -41 168 -41q81 0 129 37q51 41 51 117zM771 749l19 111h-96v135l-129 -21l-18 -114l-46 -8l-17 -103h62v-219q0 -84 44 -120q38 -30 111 -30q32 0 79 11v118 q-32 -7 -44 -7q-42 0 -42 50v197h77zM1087 724v139q-15 3 -28 3q-32 0 -55.5 -16t-33.5 -46l-10 56h-131v-471h150v306q26 31 82 31q16 0 26 -2zM1124 389h150v471h-150v-471zM1746 638q0 122 -45 179q-40 52 -111 52q-64 0 -117 -56l-8 47h-132v-645l150 25v151 q36 -11 68 -11q83 0 134 56q61 65 61 202zM1278 986q0 33 -23 56t-56 23t-56 -23t-23 -56t23 -56.5t56 -23.5t56 23.5t23 56.5zM2176 629q0 113 -48 176q-50 64 -144 64q-96 0 -151.5 -66t-55.5 -180q0 -128 63 -188q55 -55 161 -55q101 0 160 40l-16 103q-57 -31 -128 -31 q-43 0 -63 19q-23 19 -28 66h248q2 14 2 52zM2304 1280v-1280q0 -52 -38 -90t-90 -38h-2048q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h2048q52 0 90 -38t38 -90z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1558 684q61 -356 298 -556q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5zM1024 -176q16 0 16 16t-16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5zM2026 1424q8 -10 7.5 -23.5t-10.5 -22.5 l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5 l418 363q10 8 23.5 7t21.5 -11z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1040 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM503 315l877 760q-42 88 -132.5 146.5t-223.5 58.5q-93 0 -169.5 -31.5t-121.5 -80.5t-69 -103t-24 -105q0 -384 -137 -645zM1856 128 q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-180.5 74.5t-75.5 180.5l149 129h757q-166 187 -227 459l111 97q61 -356 298 -556zM1942 1520l84 -96q8 -10 7.5 -23.5t-10.5 -22.5l-1872 -1622q-10 -8 -23.5 -7t-21.5 11l-84 96q-8 10 -7.5 23.5t10.5 21.5l186 161 q-19 32 -19 66q50 42 91 88t85 119.5t74.5 158.5t50 206t19.5 260q0 152 117 282.5t307 158.5q-8 19 -8 39q0 40 28 68t68 28t68 -28t28 -68q0 -20 -8 -39q124 -18 219 -82.5t148 -157.5l418 363q10 8 23.5 7t21.5 -11z" /> -<glyph unicode="" horiz-adv-x="1408" d="M512 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM768 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1024 160v704q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-704 q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-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 23v64q0 14 9 23t23 9h309l70 167 q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1150 462v-109q0 -50 -36.5 -89t-94 -60.5t-118 -32.5t-117.5 -11q-205 0 -342.5 139t-137.5 346q0 203 136 339t339 136q34 0 75.5 -4.5t93 -18t92.5 -34t69 -56.5t28 -81v-109q0 -16 -16 -16h-118q-16 0 -16 16v70q0 43 -65.5 67.5t-137.5 24.5q-140 0 -228.5 -91.5 t-88.5 -237.5q0 -151 91.5 -249.5t233.5 -98.5q68 0 138 24t70 66v70q0 7 4.5 11.5t10.5 4.5h119q6 0 11 -4.5t5 -11.5zM768 1280q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -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 51zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" d="M972 761q0 108 -53.5 169t-147.5 61q-63 0 -124 -30.5t-110 -84.5t-79.5 -137t-30.5 -180q0 -112 53.5 -173t150.5 -61q96 0 176 66.5t122.5 166t42.5 203.5zM1536 640q0 -111 -37 -197t-98.5 -135t-131.5 -74.5t-145 -27.5q-6 0 -15.5 -0.5t-16.5 -0.5q-95 0 -142 53 q-28 33 -33 83q-52 -66 -131.5 -110t-173.5 -44q-161 0 -249.5 95.5t-88.5 269.5q0 157 66 290t179 210.5t246 77.5q87 0 155 -35.5t106 -99.5l2 19l11 56q1 6 5.5 12t9.5 6h118q5 0 13 -11q5 -5 3 -16l-120 -614q-5 -24 -5 -48q0 -39 12.5 -52t44.5 -13q28 1 57 5.5t73 24 t77 50t57 89.5t24 137q0 292 -174 466t-466 174q-130 0 -248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51q228 0 405 144q11 9 24 8t21 -12l41 -49q8 -12 7 -24q-2 -13 -12 -22q-102 -83 -227.5 -128t-258.5 -45q-156 0 -298 61 t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q344 0 556 -212t212 -556z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1698 1442q94 -94 94 -226.5t-94 -225.5l-225 -223l104 -104q10 -10 10 -23t-10 -23l-210 -210q-10 -10 -23 -10t-23 10l-105 105l-603 -603q-37 -37 -90 -37h-203l-256 -128l-64 64l128 256v203q0 53 37 90l603 603l-105 105q-10 10 -10 23t10 23l210 210q10 10 23 10 t23 -10l104 -104l223 225q93 94 225.5 94t226.5 -94zM512 64l576 576l-192 192l-576 -576v-192h192z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1615 1536q70 0 122.5 -46.5t52.5 -116.5q0 -63 -45 -151q-332 -629 -465 -752q-97 -91 -218 -91q-126 0 -216.5 92.5t-90.5 219.5q0 128 92 212l638 579q59 54 130 54zM706 502q39 -76 106.5 -130t150.5 -76l1 -71q4 -213 -129.5 -347t-348.5 -134q-123 0 -218 46.5 t-152.5 127.5t-86.5 183t-29 220q7 -5 41 -30t62 -44.5t59 -36.5t46 -17q41 0 55 37q25 66 57.5 112.5t69.5 76t88 47.5t103 25.5t125 10.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 128v-384h-1792v384q45 0 85 14t59 27.5t47 37.5q30 27 51.5 38t56.5 11t55.5 -11t52.5 -38q29 -25 47 -38t58 -27t86 -14q45 0 85 14.5t58 27t48 37.5q21 19 32.5 27t31 15t43.5 7q35 0 56.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14t85 14t59 27.5t47 37.5 q30 27 51.5 38t56.5 11q34 0 55.5 -11t51.5 -38q28 -24 47 -37.5t59 -27.5t85 -14zM1792 448v-192q-35 0 -55.5 11t-52.5 38q-29 25 -47 38t-58 27t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-22 -19 -33 -27t-31 -15t-44 -7q-35 0 -56.5 11t-51.5 38q-29 25 -47 38t-58 27 t-86 14q-45 0 -85 -14.5t-58 -27t-48 -37.5q-21 -19 -32.5 -27t-31 -15t-43.5 -7q-35 0 -56.5 11t-51.5 38q-28 24 -47 37.5t-59 27.5t-85 14q-46 0 -86 -14t-58 -27t-47 -38q-30 -27 -51.5 -38t-56.5 -11v192q0 80 56 136t136 56h64v448h256v-448h256v448h256v-448h256v448 h256v-448h64q80 0 136 -56t56 -136zM512 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1024 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51 t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150zM1536 1312q0 -77 -36 -118.5t-92 -41.5q-53 0 -90.5 37.5t-37.5 90.5q0 29 9.5 51t23.5 34t31 28t31 31.5t23.5 44.5t9.5 67q38 0 83 -74t45 -150z" /> -<glyph unicode="" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1664 1024l256 -896h-1664v576l448 576l576 -576z" /> -<glyph unicode="" horiz-adv-x="1792" d="M768 646l546 -546q-106 -108 -247.5 -168t-298.5 -60q-209 0 -385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103v-762zM955 640h773q0 -157 -60 -298.5t-168 -247.5zM1664 768h-768v768q209 0 385.5 -103t279.5 -279.5t103 -385.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M2048 0v-128h-2048v1536h128v-1408h1920zM1920 1248v-435q0 -21 -19.5 -29.5t-35.5 7.5l-121 121l-633 -633q-10 -10 -23 -10t-23 10l-233 233l-416 -416l-192 192l585 585q10 10 23 10t23 -10l233 -233l464 464l-121 121q-16 16 -7.5 35.5t29.5 19.5h435q14 0 23 -9 t9 -23z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1292 832q0 -6 10 -41q10 -29 25 -49.5t41 -34t44 -20t55 -16.5q325 -91 325 -332q0 -146 -105.5 -242.5t-254.5 -96.5q-59 0 -111.5 18.5t-91.5 45.5t-77 74.5t-63 87.5t-53.5 103.5t-43.5 103t-39.5 106.5t-35.5 95q-32 81 -61.5 133.5t-73.5 96.5t-104 64t-142 20 q-96 0 -183 -55.5t-138 -144.5t-51 -185q0 -160 106.5 -279.5t263.5 -119.5q177 0 258 95q56 63 83 116l84 -152q-15 -34 -44 -70l1 -1q-131 -152 -388 -152q-147 0 -269.5 79t-190.5 207.5t-68 274.5q0 105 43.5 206t116 176.5t172 121.5t204.5 46q87 0 159 -19t123.5 -50 t95 -80t72.5 -99t58.5 -117t50.5 -124.5t50 -130.5t55 -127q96 -200 233 -200q81 0 138.5 48.5t57.5 128.5q0 42 -19 72t-50.5 46t-72.5 31.5t-84.5 27t-87.5 34t-81 52t-65 82t-39 122.5q-3 16 -3 33q0 110 87.5 192t198.5 78q78 -3 120.5 -14.5t90.5 -53.5h-1 q12 -11 23 -24.5t26 -36t19 -27.5l-129 -99q-26 49 -54 70v1q-23 21 -97 21q-49 0 -84 -33t-35 -83z" /> -<glyph unicode="" d="M1432 484q0 173 -234 239q-35 10 -53 16.5t-38 25t-29 46.5q0 2 -2 8.5t-3 12t-1 7.5q0 36 24.5 59.5t60.5 23.5q54 0 71 -15h-1q20 -15 39 -51l93 71q-39 54 -49 64q-33 29 -67.5 39t-85.5 10q-80 0 -142 -57.5t-62 -137.5q0 -7 2 -23q16 -96 64.5 -140t148.5 -73 q29 -8 49 -15.5t45 -21.5t38.5 -34.5t13.5 -46.5v-5q1 -58 -40.5 -93t-100.5 -35q-97 0 -167 144q-23 47 -51.5 121.5t-48 125.5t-54 110.5t-74 95.5t-103.5 60.5t-147 24.5q-101 0 -192 -56t-144 -148t-50 -192v-1q4 -108 50.5 -199t133.5 -147.5t196 -56.5q186 0 279 110 q20 27 31 51l-60 109q-42 -80 -99 -116t-146 -36q-115 0 -191 87t-76 204q0 105 82 189t186 84q112 0 170 -53.5t104 -172.5q8 -21 25.5 -68.5t28.5 -76.5t31.5 -74.5t38.5 -74t45.5 -62.5t55.5 -53.5t66 -33t80 -13.5q107 0 183 69.5t76 174.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1152 640q0 104 -40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM1920 640q0 104 -40.5 198.5 t-109.5 163.5t-163.5 109.5t-198.5 40.5h-386q119 -90 188.5 -224t69.5 -288t-69.5 -288t-188.5 -224h386q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5zM2048 640q0 -130 -51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5 t-136.5 204t-51 248.5t51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M0 640q0 130 51 248.5t136.5 204t204 136.5t248.5 51h768q130 0 248.5 -51t204 -136.5t136.5 -204t51 -248.5t-51 -248.5t-136.5 -204t-204 -136.5t-248.5 -51h-768q-130 0 -248.5 51t-204 136.5t-136.5 204t-51 248.5zM1408 128q104 0 198.5 40.5t163.5 109.5 t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" /> -<glyph unicode="" horiz-adv-x="2304" d="M762 384h-314q-40 0 -57.5 35t6.5 67l188 251q-65 31 -137 31q-132 0 -226 -94t-94 -226t94 -226t226 -94q115 0 203 72.5t111 183.5zM576 512h186q-18 85 -75 148zM1056 512l288 384h-480l-99 -132q105 -103 126 -252h165zM2176 448q0 132 -94 226t-226 94 q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94t226 94t94 226zM2304 448q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 97 39.5 183.5t109.5 149.5l-65 98l-353 -469 q-18 -26 -51 -26h-197q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q114 0 215 -55l137 183h-224q-26 0 -45 19t-19 45t19 45t45 19h384v-128h435l-85 128h-222q-26 0 -45 19t-19 45t19 45t45 19h256q33 0 53 -28l267 -400 q91 44 192 44q185 0 316.5 -131.5t131.5 -316.5z" /> -<glyph unicode="" d="M384 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1408 320q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1362 716l-72 384q-5 23 -22.5 37.5t-40.5 14.5 h-918q-23 0 -40.5 -14.5t-22.5 -37.5l-72 -384q-5 -30 14 -53t49 -23h1062q30 0 49 23t14 53zM1136 1328q0 20 -14 34t-34 14h-640q-20 0 -34 -14t-14 -34t14 -34t34 -14h640q20 0 34 14t14 34zM1536 603v-603h-128v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5v128h-768v-128q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5v128h-128v603q0 112 25 223l103 454q9 78 97.5 137t230 89t312.5 30t312.5 -30t230 -89t97.5 -137l105 -454q23 -102 23 -223z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1463 704q0 -35 -25 -60.5t-61 -25.5h-702q-36 0 -61 25.5t-25 60.5t25 60.5t61 25.5h702q36 0 61 -25.5t25 -60.5zM1677 704q0 86 -23 170h-982q-36 0 -61 25t-25 60q0 36 25 61t61 25h908q-88 143 -235 227t-320 84q-177 0 -327.5 -87.5t-238 -237.5t-87.5 -327 q0 -86 23 -170h982q36 0 61 -25t25 -60q0 -36 -25 -61t-61 -25h-908q88 -143 235.5 -227t320.5 -84q132 0 253 51.5t208 139t139 208t52 253.5zM2048 959q0 -35 -25 -60t-61 -25h-131q17 -85 17 -170q0 -167 -65.5 -319.5t-175.5 -263t-262.5 -176t-319.5 -65.5 q-246 0 -448.5 133t-301.5 350h-189q-36 0 -61 25t-25 61q0 35 25 60t61 25h132q-17 85 -17 170q0 167 65.5 319.5t175.5 263t262.5 176t320.5 65.5q245 0 447.5 -133t301.5 -350h188q36 0 61 -25t25 -61z" /> -<glyph unicode="" horiz-adv-x="1280" d="M953 1158l-114 -328l117 -21q165 451 165 518q0 56 -38 56q-57 0 -130 -225zM654 471l33 -88q37 42 71 67l-33 5.5t-38.5 7t-32.5 8.5zM362 1367q0 -98 159 -521q18 10 49 10q15 0 75 -5l-121 351q-75 220 -123 220q-19 0 -29 -17.5t-10 -37.5zM283 608q0 -36 51.5 -119 t117.5 -153t100 -70q14 0 25.5 13t11.5 27q0 24 -32 102q-13 32 -32 72t-47.5 89t-61.5 81t-62 32q-20 0 -45.5 -27t-25.5 -47zM125 273q0 -41 25 -104q59 -145 183.5 -227t281.5 -82q227 0 382 170q152 169 152 427q0 43 -1 67t-11.5 62t-30.5 56q-56 49 -211.5 75.5 t-270.5 26.5q-37 0 -49 -11q-12 -5 -12 -35q0 -34 21.5 -60t55.5 -40t77.5 -23.5t87.5 -11.5t85 -4t70 0h23q24 0 40 -19q15 -19 19 -55q-28 -28 -96 -54q-61 -22 -93 -46q-64 -46 -108.5 -114t-44.5 -137q0 -31 18.5 -88.5t18.5 -87.5l-3 -12q-4 -12 -4 -14 q-137 10 -146 216q-8 -2 -41 -2q2 -7 2 -21q0 -53 -40.5 -89.5t-94.5 -36.5q-82 0 -166.5 78t-84.5 159q0 34 33 67q52 -64 60 -76q77 -104 133 -104q12 0 26.5 8.5t14.5 20.5q0 34 -87.5 145t-116.5 111q-43 0 -70 -44.5t-27 -90.5zM11 264q0 101 42.5 163t136.5 88 q-28 74 -28 104q0 62 61 123t122 61q29 0 70 -15q-163 462 -163 567q0 80 41 130.5t119 50.5q131 0 325 -581q6 -17 8 -23q6 16 29 79.5t43.5 118.5t54 127.5t64.5 123t70.5 86.5t76.5 36q71 0 112 -49t41 -122q0 -108 -159 -550q61 -15 100.5 -46t58.5 -78t26 -93.5 t7 -110.5q0 -150 -47 -280t-132 -225t-211 -150t-278 -55q-111 0 -223 42q-149 57 -258 191.5t-109 286.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M785 528h207q-14 -158 -98.5 -248.5t-214.5 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-203q-5 64 -35.5 99t-81.5 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t40 -51.5t66 -18q95 0 109 139zM1497 528h206 q-14 -158 -98 -248.5t-214 -90.5q-162 0 -254.5 116t-92.5 316q0 194 93 311.5t233 117.5q148 0 232 -87t97 -247h-204q-4 64 -35 99t-81 35q-57 0 -88.5 -60.5t-31.5 -177.5q0 -48 5 -84t18 -69.5t39.5 -51.5t65.5 -18q49 0 76.5 38t33.5 101zM1856 647q0 207 -15.5 307 t-60.5 161q-6 8 -13.5 14t-21.5 15t-16 11q-86 63 -697 63q-625 0 -710 -63q-5 -4 -17.5 -11.5t-21 -14t-14.5 -14.5q-45 -60 -60 -159.5t-15 -308.5q0 -208 15 -307.5t60 -160.5q6 -8 15 -15t20.5 -14t17.5 -12q44 -33 239.5 -49t470.5 -16q610 0 697 65q5 4 17 11t20.5 14 t13.5 16q46 60 61 159t15 309zM2048 1408v-1536h-2048v1536h2048z" /> -<glyph unicode="" d="M992 912v-496q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v496q0 112 -80 192t-192 80h-272v-1152q0 -14 -9 -23t-23 -9h-160q-14 0 -23 9t-9 23v1344q0 14 9 23t23 9h464q135 0 249 -66.5t180.5 -180.5t66.5 -249zM1376 1376v-880q0 -135 -66.5 -249t-180.5 -180.5 t-249 -66.5h-464q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h160q14 0 23 -9t9 -23v-768h272q112 0 192 80t80 192v880q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> -<glyph unicode="" d="M1311 694v-114q0 -24 -13.5 -38t-37.5 -14h-202q-24 0 -38 14t-14 38v114q0 24 14 38t38 14h202q24 0 37.5 -14t13.5 -38zM821 464v250q0 53 -32.5 85.5t-85.5 32.5h-133q-68 0 -96 -52q-28 52 -96 52h-130q-53 0 -85.5 -32.5t-32.5 -85.5v-250q0 -22 21 -22h55 q22 0 22 22v230q0 24 13.5 38t38.5 14h94q24 0 38 -14t14 -38v-230q0 -22 21 -22h54q22 0 22 22v230q0 24 14 38t38 14h97q24 0 37.5 -14t13.5 -38v-230q0 -22 22 -22h55q21 0 21 22zM1410 560v154q0 53 -33 85.5t-86 32.5h-264q-53 0 -86 -32.5t-33 -85.5v-410 q0 -21 22 -21h55q21 0 21 21v180q31 -42 94 -42h191q53 0 86 32.5t33 85.5zM1536 1176v-1072q0 -96 -68 -164t-164 -68h-1072q-96 0 -164 68t-68 164v1072q0 96 68 164t164 68h1072q96 0 164 -68t68 -164z" /> -<glyph unicode="" d="M915 450h-294l147 551zM1001 128h311l-324 1024h-440l-324 -1024h311l383 314zM1536 1120v-960q0 -118 -85 -203t-203 -85h-960q-118 0 -203 85t-85 203v960q0 118 85 203t203 85h960q118 0 203 -85t85 -203z" /> -<glyph unicode="" horiz-adv-x="2048" d="M2048 641q0 -21 -13 -36.5t-33 -19.5l-205 -356q3 -9 3 -18q0 -20 -12.5 -35.5t-32.5 -19.5l-193 -337q3 -8 3 -16q0 -23 -16.5 -40t-40.5 -17q-25 0 -41 18h-400q-17 -20 -43 -20t-43 20h-399q-17 -20 -43 -20q-23 0 -40 16.5t-17 40.5q0 8 4 20l-193 335 q-20 4 -32.5 19.5t-12.5 35.5q0 9 3 18l-206 356q-20 5 -32.5 20.5t-12.5 35.5q0 21 13.5 36.5t33.5 19.5l199 344q0 1 -0.5 3t-0.5 3q0 36 34 51l209 363q-4 10 -4 18q0 24 17 40.5t40 16.5q26 0 44 -21h396q16 21 43 21t43 -21h398q18 21 44 21q23 0 40 -16.5t17 -40.5 q0 -6 -4 -18l207 -358q23 -1 39 -17.5t16 -38.5q0 -13 -7 -27l187 -324q19 -4 31.5 -19.5t12.5 -35.5zM1063 -158h389l-342 354h-143l-342 -354h360q18 16 39 16t39 -16zM112 654q1 -4 1 -13q0 -10 -2 -15l208 -360q2 0 4.5 -1t5.5 -2.5l5 -2.5l188 199v347l-187 194 q-13 -8 -29 -10zM986 1438h-388l190 -200l554 200h-280q-16 -16 -38 -16t-38 16zM1689 226q1 6 5 11l-64 68l-17 -79h76zM1583 226l22 105l-252 266l-296 -307l63 -64h463zM1495 -142l16 28l65 310h-427l333 -343q8 4 13 5zM578 -158h5l342 354h-373v-335l4 -6q14 -5 22 -13 zM552 226h402l64 66l-309 321l-157 -166v-221zM359 226h163v189l-168 -177q4 -8 5 -12zM358 1051q0 -1 0.5 -2t0.5 -2q0 -16 -8 -29l171 -177v269zM552 1121v-311l153 -157l297 314l-223 236zM556 1425l-4 -8v-264l205 74l-191 201q-6 -2 -10 -3zM1447 1438h-16l-621 -224 l213 -225zM1023 946l-297 -315l311 -319l296 307zM688 634l-136 141v-284zM1038 270l-42 -44h85zM1374 618l238 -251l132 624l-3 5l-1 1zM1718 1018q-8 13 -8 29v2l-216 376q-5 1 -13 5l-437 -463l310 -327zM522 1142v223l-163 -282zM522 196h-163l163 -283v283zM1607 196 l-48 -227l130 227h-82zM1729 266l207 361q-2 10 -2 14q0 1 3 16l-171 296l-129 -612l77 -82q5 3 15 7z" /> -<glyph unicode="" d="M0 856q0 131 91.5 226.5t222.5 95.5h742l352 358v-1470q0 -132 -91.5 -227t-222.5 -95h-780q-131 0 -222.5 95t-91.5 227v790zM1232 102l-176 180v425q0 46 -32 79t-78 33h-484q-46 0 -78 -33t-32 -79v-492q0 -46 32.5 -79.5t77.5 -33.5h770z" /> -<glyph unicode="" d="M934 1386q-317 -121 -556 -362.5t-358 -560.5q-20 89 -20 176q0 208 102.5 384.5t278.5 279t384 102.5q82 0 169 -19zM1203 1267q93 -65 164 -155q-389 -113 -674.5 -400.5t-396.5 -676.5q-93 72 -155 162q112 386 395 671t667 399zM470 -67q115 356 379.5 622t619.5 384 q40 -92 54 -195q-292 -120 -516 -345t-343 -518q-103 14 -194 52zM1536 -125q-193 50 -367 115q-135 -84 -290 -107q109 205 274 370.5t369 275.5q-21 -152 -101 -284q65 -175 115 -370z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1893 1144l155 -1272q-131 0 -257 57q-200 91 -393 91q-226 0 -374 -148q-148 148 -374 148q-193 0 -393 -91q-128 -57 -252 -57h-5l155 1272q224 127 482 127q233 0 387 -106q154 106 387 106q258 0 482 -127zM1398 157q129 0 232 -28.5t260 -93.5l-124 1021 q-171 78 -368 78q-224 0 -374 -141q-150 141 -374 141q-197 0 -368 -78l-124 -1021q105 43 165.5 65t148.5 39.5t178 17.5q202 0 374 -108q172 108 374 108zM1438 191l-55 907q-211 -4 -359 -155q-152 155 -374 155q-176 0 -336 -66l-114 -941q124 51 228.5 76t221.5 25 q209 0 374 -102q172 107 374 102z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1500 165v733q0 21 -15 36t-35 15h-93q-20 0 -35 -15t-15 -36v-733q0 -20 15 -35t35 -15h93q20 0 35 15t15 35zM1216 165v531q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-531q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM924 165v429q0 20 -15 35t-35 15h-101 q-20 0 -35 -15t-15 -35v-429q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM632 165v362q0 20 -15 35t-35 15h-101q-20 0 -35 -15t-15 -35v-362q0 -20 15 -35t35 -15h101q20 0 35 15t15 35zM2048 311q0 -166 -118 -284t-284 -118h-1244q-166 0 -284 118t-118 284 q0 116 63 214.5t168 148.5q-10 34 -10 73q0 113 80.5 193.5t193.5 80.5q102 0 180 -67q45 183 194 300t338 117q149 0 275 -73.5t199.5 -199.5t73.5 -275q0 -66 -14 -122q135 -33 221 -142.5t86 -247.5z" /> -<glyph unicode="" d="M0 1536h1536v-1392l-776 -338l-760 338v1392zM1436 209v926h-1336v-926l661 -294zM1436 1235v201h-1336v-201h1336zM181 937v-115h-37v115h37zM181 789v-115h-37v115h37zM181 641v-115h-37v115h37zM181 493v-115h-37v115h37zM181 345v-115h-37v115h37zM207 202l15 34 l105 -47l-15 -33zM343 142l15 34l105 -46l-15 -34zM478 82l15 34l105 -46l-15 -34zM614 23l15 33l104 -46l-15 -34zM797 10l105 46l15 -33l-105 -47zM932 70l105 46l15 -34l-105 -46zM1068 130l105 46l15 -34l-105 -46zM1203 189l105 47l15 -34l-105 -46zM259 1389v-36h-114 v36h114zM421 1389v-36h-115v36h115zM583 1389v-36h-115v36h115zM744 1389v-36h-114v36h114zM906 1389v-36h-114v36h114zM1068 1389v-36h-115v36h115zM1230 1389v-36h-115v36h115zM1391 1389v-36h-114v36h114zM181 1049v-79h-37v115h115v-36h-78zM421 1085v-36h-115v36h115z M583 1085v-36h-115v36h115zM744 1085v-36h-114v36h114zM906 1085v-36h-114v36h114zM1068 1085v-36h-115v36h115zM1230 1085v-36h-115v36h115zM1355 970v79h-78v36h115v-115h-37zM1355 822v115h37v-115h-37zM1355 674v115h37v-115h-37zM1355 526v115h37v-115h-37zM1355 378 v115h37v-115h-37zM1355 230v115h37v-115h-37zM760 265q-129 0 -221 91.5t-92 221.5q0 129 92 221t221 92q130 0 221.5 -92t91.5 -221q0 -130 -91.5 -221.5t-221.5 -91.5zM595 646q0 -36 19.5 -56.5t49.5 -25t64 -7t64 -2t49.5 -9t19.5 -30.5q0 -49 -112 -49q-97 0 -123 51 h-3l-31 -63q67 -42 162 -42q29 0 56.5 5t55.5 16t45.5 33t17.5 53q0 46 -27.5 69.5t-67.5 27t-79.5 3t-67 5t-27.5 25.5q0 21 20.5 33t40.5 15t41 3q34 0 70.5 -11t51.5 -34h3l30 58q-3 1 -21 8.5t-22.5 9t-19.5 7t-22 7t-20 4.5t-24 4t-23 1q-29 0 -56.5 -5t-54 -16.5 t-43 -34t-16.5 -53.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M863 504q0 112 -79.5 191.5t-191.5 79.5t-191 -79.5t-79 -191.5t79 -191t191 -79t191.5 79t79.5 191zM1726 505q0 112 -79 191t-191 79t-191.5 -79t-79.5 -191q0 -113 79.5 -192t191.5 -79t191 79.5t79 191.5zM2048 1314v-1348q0 -44 -31.5 -75.5t-76.5 -31.5h-1832 q-45 0 -76.5 31.5t-31.5 75.5v1348q0 44 31.5 75.5t76.5 31.5h431q44 0 76 -31.5t32 -75.5v-161h754v161q0 44 32 75.5t76 31.5h431q45 0 76.5 -31.5t31.5 -75.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1430 953zM1690 749q148 0 253 -98.5t105 -244.5q0 -157 -109 -261.5t-267 -104.5q-85 0 -162 27.5t-138 73.5t-118 106t-109 126.5t-103.5 132.5t-108.5 126t-117 106t-136 73.5t-159 27.5q-154 0 -251.5 -91.5t-97.5 -244.5q0 -157 104 -250t263 -93q100 0 208 37.5 t193 98.5q5 4 21 18.5t30 24t22 9.5q14 0 24.5 -10.5t10.5 -24.5q0 -24 -60 -77q-101 -88 -234.5 -142t-260.5 -54q-133 0 -245.5 58t-180 165t-67.5 241q0 205 141.5 341t347.5 136q120 0 226.5 -43.5t185.5 -113t151.5 -153t139 -167.5t133.5 -153.5t149.5 -113 t172.5 -43.5q102 0 168.5 61.5t66.5 162.5q0 95 -64.5 159t-159.5 64q-30 0 -81.5 -18.5t-68.5 -18.5q-20 0 -35.5 15t-15.5 35q0 18 8.5 57t8.5 59q0 159 -107.5 263t-266.5 104q-58 0 -111.5 -18.5t-84 -40.5t-55.5 -40.5t-33 -18.5q-15 0 -25.5 10.5t-10.5 25.5 q0 19 25 46q59 67 147 103.5t182 36.5q191 0 318 -125.5t127 -315.5q0 -37 -4 -66q57 15 115 15z" /> -<glyph unicode="" horiz-adv-x="1664" d="M1216 832q0 26 -19 45t-45 19h-128v128q0 26 -19 45t-45 19t-45 -19t-19 -45v-128h-128q-26 0 -45 -19t-19 -45t19 -45t45 -19h128v-128q0 -26 19 -45t45 -19t45 19t19 45v128h128q26 0 45 19t19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19t-45 -19l-147 -146v293q0 26 -19 45t-45 19t-45 -19t-19 -45v-293l-147 146q-19 19 -45 19t-45 -19t-19 -45t19 -45l256 -256q19 -19 45 -19t45 19l256 256q19 19 19 45zM640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920 q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> -<glyph unicode="" horiz-adv-x="2048" d="M212 768l623 -665l-300 665h-323zM1024 -4l349 772h-698zM538 896l204 384h-262l-288 -384h346zM1213 103l623 665h-323zM683 896h682l-204 384h-274zM1510 896h346l-288 384h-262zM1651 1382l384 -512q14 -18 13 -41.5t-17 -40.5l-960 -1024q-18 -20 -47 -20t-47 20 l-960 1024q-16 17 -17 40.5t13 41.5l384 512q18 26 51 26h1152q33 0 51 -26z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1811 -19q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83q19 19 45 19t45 -19l83 -83l83 83 q19 19 45 19t45 -19l83 -83zM237 19q-19 -19 -45 -19t-45 19l-128 128l90 90l83 -82l83 82q19 19 45 19t45 -19l83 -82l64 64v293l-210 314q-17 26 -7 56.5t40 40.5l177 58v299h128v128h256v128h256v-128h256v-128h128v-299l177 -58q30 -10 40 -40.5t-7 -56.5l-210 -314 v-293l19 18q19 19 45 19t45 -19l83 -82l83 82q19 19 45 19t45 -19l128 -128l-90 -90l-83 83l-83 -83q-18 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83l-83 -83 q-19 -19 -45 -19t-45 19l-83 83l-83 -83q-19 -19 -45 -19t-45 19l-83 83zM640 1152v-128l384 128l384 -128v128h-128v128h-512v-128h-128z" /> -<glyph unicode="" d="M576 0l96 448l-96 128l-128 64zM832 0l128 640l-128 -64l-96 -128zM992 1010q-2 4 -4 6q-10 8 -96 8q-70 0 -167 -19q-7 -2 -21 -2t-21 2q-97 19 -167 19q-86 0 -96 -8q-2 -2 -4 -6q2 -18 4 -27q2 -3 7.5 -6.5t7.5 -10.5q2 -4 7.5 -20.5t7 -20.5t7.5 -17t8.5 -17t9 -14 t12 -13.5t14 -9.5t17.5 -8t20.5 -4t24.5 -2q36 0 59 12.5t32.5 30t14.5 34.5t11.5 29.5t17.5 12.5h12q11 0 17.5 -12.5t11.5 -29.5t14.5 -34.5t32.5 -30t59 -12.5q13 0 24.5 2t20.5 4t17.5 8t14 9.5t12 13.5t9 14t8.5 17t7.5 17t7 20.5t7.5 20.5q2 7 7.5 10.5t7.5 6.5 q2 9 4 27zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 61 4.5 118t19 125.5t37.5 123.5t63.5 103.5t93.5 74.5l-90 220h214q-22 64 -22 128q0 12 2 32q-194 40 -194 96q0 57 210 99q17 62 51.5 134t70.5 114q32 37 76 37q30 0 84 -31t84 -31t84 31 t84 31q44 0 76 -37q36 -42 70.5 -114t51.5 -134q210 -42 210 -99q0 -56 -194 -96q7 -81 -20 -160h214l-82 -225q63 -33 107.5 -96.5t65.5 -143.5t29 -151.5t8 -148.5z" /> -<glyph unicode="" horiz-adv-x="2304" d="M2301 500q12 -103 -22 -198.5t-99 -163.5t-158.5 -106t-196.5 -31q-161 11 -279.5 125t-134.5 274q-12 111 27.5 210.5t118.5 170.5l-71 107q-96 -80 -151 -194t-55 -244q0 -27 -18.5 -46.5t-45.5 -19.5h-256h-69q-23 -164 -149 -274t-294 -110q-185 0 -316.5 131.5 t-131.5 316.5t131.5 316.5t316.5 131.5q76 0 152 -27l24 45q-123 110 -304 110h-64q-26 0 -45 19t-19 45t19 45t45 19h128q78 0 145 -13.5t116.5 -38.5t71.5 -39.5t51 -36.5h512h115l-85 128h-222q-30 0 -49 22.5t-14 52.5q4 23 23 38t43 15h253q33 0 53 -28l70 -105 l114 114q19 19 46 19h101q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-179l115 -172q131 63 275 36q143 -26 244 -134.5t118 -253.5zM448 128q115 0 203 72.5t111 183.5h-314q-35 0 -55 31q-18 32 -1 63l147 277q-47 13 -91 13q-132 0 -226 -94t-94 -226t94 -226 t226 -94zM1856 128q132 0 226 94t94 226t-94 226t-226 94q-60 0 -121 -24l174 -260q15 -23 10 -49t-27 -40q-15 -11 -36 -11q-35 0 -53 29l-174 260q-93 -95 -93 -225q0 -132 94 -226t226 -94z" /> -<glyph unicode="" d="M1408 0q0 -63 -61.5 -113.5t-164 -81t-225 -46t-253.5 -15.5t-253.5 15.5t-225 46t-164 81t-61.5 113.5q0 49 33 88.5t91 66.5t118 44.5t131 29.5q26 5 48 -10.5t26 -41.5q5 -26 -10.5 -48t-41.5 -26q-58 -10 -106 -23.5t-76.5 -25.5t-48.5 -23.5t-27.5 -19.5t-8.5 -12 q3 -11 27 -26.5t73 -33t114 -32.5t160.5 -25t201.5 -10t201.5 10t160.5 25t114 33t73 33.5t27 27.5q-1 4 -8.5 11t-27.5 19t-48.5 23.5t-76.5 25t-106 23.5q-26 4 -41.5 26t-10.5 48q4 26 26 41.5t48 10.5q71 -12 131 -29.5t118 -44.5t91 -66.5t33 -88.5zM1024 896v-384 q0 -26 -19 -45t-45 -19h-64v-384q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v384h-64q-26 0 -45 19t-19 45v384q0 53 37.5 90.5t90.5 37.5h384q53 0 90.5 -37.5t37.5 -90.5zM928 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5 t158.5 -65.5t65.5 -158.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 512h305q-5 -6 -10 -10.5t-9 -7.5l-3 -4l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-5 2 -21 20h369q22 0 39.5 13.5t22.5 34.5l70 281l190 -667q6 -20 23 -33t39 -13q21 0 38 13t23 33l146 485l56 -112q18 -35 57 -35zM1792 940q0 -145 -103 -300h-369l-111 221 q-8 17 -25.5 27t-36.5 8q-45 -5 -56 -46l-129 -430l-196 686q-6 20 -23.5 33t-39.5 13t-39 -13.5t-22 -34.5l-116 -464h-423q-103 155 -103 300q0 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 -124 t127 -344z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292 q11 134 80.5 249t182 188t245.5 88q170 19 319 -54t236 -212t87 -306zM128 960q0 -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="" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h416q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-419 -420q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5 t431 200.5q144 12 276.5 -30.5t236.5 -129.5l419 419h-261q-14 0 -23 9t-9 23v64zM704 -128q117 0 223.5 45.5t184 123t123 184t45.5 223.5t-45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123 t223.5 -45.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M830 1220q145 -72 233.5 -210.5t88.5 -305.5q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5 t-147.5 384.5q0 167 88.5 305.5t233.5 210.5q-165 96 -228 273q-6 16 3.5 29.5t26.5 13.5h69q21 0 29 -20q44 -106 140 -171t214 -65t214 65t140 171q8 20 37 20h61q17 0 26.5 -13.5t3.5 -29.5q-63 -177 -228 -273zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" d="M1024 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-149 16 -270.5 103t-186.5 223.5t-53 291.5q16 204 160 353.5t347 172.5q118 14 228 -19t198 -103l255 254h-134q-14 0 -23 9t-9 23v64zM576 256q185 0 316.5 131.5t131.5 316.5t-131.5 316.5 t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1280 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q126 -158 126 -359q0 -221 -147.5 -384.5t-364.5 -187.5v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64 q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-217 24 -364.5 187.5t-147.5 384.5q0 201 126 359l-52 53l-101 -111q-9 -10 -22 -10.5t-23 7.5l-48 44q-10 8 -10.5 21.5t8.5 23.5l105 115l-111 112v-134q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9 t-9 23v288q0 26 19 45t45 19h288q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-133l106 -107l86 94q9 10 22 10.5t23 -7.5l48 -44q10 -8 10.5 -21.5t-8.5 -23.5l-90 -99l57 -56q158 126 359 126t359 -126l255 254h-134q-14 0 -23 9t-9 23v64zM832 256q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1790 1007q12 -155 -52.5 -292t-186 -224t-271.5 -103v-260h224q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-512v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23 t23 9h224v260q-150 16 -271.5 103t-186 224t-52.5 292q17 206 164.5 356.5t352.5 169.5q206 21 377 -94q171 115 377 94q205 -19 352.5 -169.5t164.5 -356.5zM896 647q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM576 512q115 0 218 57q-154 165 -154 391 q0 224 154 391q-103 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5zM1152 128v260q-137 15 -256 94q-119 -79 -256 -94v-260h512zM1216 512q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5q-115 0 -218 -57q154 -167 154 -391 q0 -226 -154 -391q103 -57 218 -57z" /> -<glyph unicode="" horiz-adv-x="1920" d="M1536 1120q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-31 -182 -166 -312t-318 -156q-210 -29 -384.5 80t-241.5 300q-117 6 -221 57.5t-177.5 133t-113.5 192.5t-32 230 q9 135 78 252t182 191.5t248 89.5q118 14 227.5 -19t198.5 -103l255 254h-134q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q59 -74 93 -169q182 -9 328 -124l255 254h-134q-14 0 -23 9 t-9 23v64zM1024 704q0 20 -4 58q-162 -25 -271 -150t-109 -292q0 -20 4 -58q162 25 271 150t109 292zM128 704q0 -168 111 -294t276 -149q-3 29 -3 59q0 210 135 369.5t338 196.5q-53 120 -163.5 193t-245.5 73q-185 0 -316.5 -131.5t-131.5 -316.5zM1088 -128 q185 0 316.5 131.5t131.5 316.5q0 168 -111 294t-276 149q3 -29 3 -59q0 -210 -135 -369.5t-338 -196.5q53 -120 163.5 -193t245.5 -73z" /> -<glyph unicode="" horiz-adv-x="2048" d="M1664 1504q0 14 9 23t23 9h288q26 0 45 -19t19 -45v-288q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v134l-254 -255q76 -95 107.5 -214t9.5 -247q-32 -180 -164.5 -310t-313.5 -157q-223 -34 -409 90q-117 -78 -256 -93v-132h96q14 0 23 -9t9 -23v-64q0 -14 -9 -23 t-23 -9h-96v-96q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v96h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h96v132q-155 17 -279.5 109.5t-187 237.5t-39.5 307q25 187 159.5 322.5t320.5 164.5q224 34 410 -90q146 97 320 97q201 0 359 -126l255 254h-134q-14 0 -23 9 t-9 23v64zM896 391q128 131 128 313t-128 313q-128 -131 -128 -313t128 -313zM128 704q0 -185 131.5 -316.5t316.5 -131.5q117 0 218 57q-154 167 -154 391t154 391q-101 57 -218 57q-185 0 -316.5 -131.5t-131.5 -316.5zM1216 256q185 0 316.5 131.5t131.5 316.5 t-131.5 316.5t-316.5 131.5q-117 0 -218 -57q154 -167 154 -391t-154 -391q101 -57 218 -57z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1728 1536q26 0 45 -19t19 -45v-416q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v262l-229 -230l156 -156q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-156 157l-99 -100q87 -104 129.5 -236.5t30.5 -276.5q-22 -250 -200.5 -431t-428.5 -206q-163 -17 -314 39.5 t-256.5 162t-162 256.5t-39.5 314q25 250 206 428.5t431 200.5q144 12 276.5 -30.5t236.5 -129.5l99 99l-156 156q-9 10 -9 23t9 22l46 46q9 9 22 9t23 -9l156 -156l229 229h-261q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h416zM1280 448q0 117 -45.5 223.5t-123 184t-184 123 t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M640 892q217 -24 364.5 -187.5t147.5 -384.5q0 -167 -87 -306t-236 -212t-319 -54q-133 15 -245.5 88t-182 188t-80.5 249q-12 155 52.5 292t186 224t271.5 103v132h-160q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h160v165l-92 -92q-10 -9 -23 -9t-22 9l-46 46q-9 9 -9 22 t9 23l202 201q19 19 45 19t45 -19l202 -201q9 -10 9 -23t-9 -22l-46 -46q-9 -9 -22 -9t-23 9l-92 92v-165h160q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-160v-132zM576 -128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5 t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="2048" d="M2029 685q19 -19 19 -45t-19 -45l-294 -294q-9 -10 -22.5 -10t-22.5 10l-45 45q-10 9 -10 22.5t10 22.5l185 185h-294v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-131q-12 -119 -67 -226t-139 -183.5t-196.5 -121.5t-234.5 -45q-180 0 -330.5 91t-234.5 247 t-74 337q8 162 94 300t226.5 219.5t302.5 85.5q166 4 310.5 -71.5t235.5 -208.5t107 -296h131v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h294l-185 185q-10 9 -10 22.5t10 22.5l45 45q9 10 22.5 10t22.5 -10zM640 128q104 0 198.5 40.5t163.5 109.5t109.5 163.5 t40.5 198.5t-40.5 198.5t-109.5 163.5t-163.5 109.5t-198.5 40.5t-198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5z" /> -<glyph unicode="" horiz-adv-x="1280" d="M1152 960q0 -221 -147.5 -384.5t-364.5 -187.5v-612q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v612q-217 24 -364.5 187.5t-147.5 384.5q0 117 45.5 223.5t123 184t184 123t223.5 45.5t223.5 -45.5t184 -123t123 -184t45.5 -223.5zM576 512q185 0 316.5 131.5 t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" d="M1451 1408q35 0 60 -25t25 -60v-1366q0 -35 -25 -60t-60 -25h-391v595h199l30 232h-229v148q0 56 23.5 84t91.5 28l122 1v207q-63 9 -178 9q-136 0 -217.5 -80t-81.5 -226v-171h-200v-232h200v-595h-735q-35 0 -60 25t-25 60v1366q0 35 25 60t60 25h1366z" /> -<glyph unicode="" horiz-adv-x="1280" d="M0 939q0 108 37.5 203.5t103.5 166.5t152 123t185 78t202 26q158 0 294 -66.5t221 -193.5t85 -287q0 -96 -19 -188t-60 -177t-100 -149.5t-145 -103t-189 -38.5q-68 0 -135 32t-96 88q-10 -39 -28 -112.5t-23.5 -95t-20.5 -71t-26 -71t-32 -62.5t-46 -77.5t-62 -86.5 l-14 -5l-9 10q-15 157 -15 188q0 92 21.5 206.5t66.5 287.5t52 203q-32 65 -32 169q0 83 52 156t132 73q61 0 95 -40.5t34 -102.5q0 -66 -44 -191t-44 -187q0 -63 45 -104.5t109 -41.5q55 0 102 25t78.5 68t56 95t38 110.5t20 111t6.5 99.5q0 173 -109.5 269.5t-285.5 96.5 q-200 0 -334 -129.5t-134 -328.5q0 -44 12.5 -85t27 -65t27 -45.5t12.5 -30.5q0 -28 -15 -73t-37 -45q-2 0 -17 3q-51 15 -90.5 56t-61 94.5t-32.5 108t-11 106.5z" /> -<glyph unicode="" d="M985 562q13 0 97.5 -44t89.5 -53q2 -5 2 -15q0 -33 -17 -76q-16 -39 -71 -65.5t-102 -26.5q-57 0 -190 62q-98 45 -170 118t-148 185q-72 107 -71 194v8q3 91 74 158q24 22 52 22q6 0 18 -1.5t19 -1.5q19 0 26.5 -6.5t15.5 -27.5q8 -20 33 -88t25 -75q0 -21 -34.5 -57.5 t-34.5 -46.5q0 -7 5 -15q34 -73 102 -137q56 -53 151 -101q12 -7 22 -7q15 0 54 48.5t52 48.5zM782 32q127 0 243.5 50t200.5 134t134 200.5t50 243.5t-50 243.5t-134 200.5t-200.5 134t-243.5 50t-243.5 -50t-200.5 -134t-134 -200.5t-50 -243.5q0 -203 120 -368l-79 -233 l242 77q158 -104 345 -104zM782 1414q153 0 292.5 -60t240.5 -161t161 -240.5t60 -292.5t-60 -292.5t-161 -240.5t-240.5 -161t-292.5 -60q-195 0 -365 94l-417 -134l136 405q-108 178 -108 389q0 153 60 292.5t161 240.5t240.5 161t292.5 60z" /> -<glyph unicode="" horiz-adv-x="1792" d="M128 128h1024v128h-1024v-128zM128 640h1024v128h-1024v-128zM1696 192q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM128 1152h1024v128h-1024v-128zM1696 704q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1696 1216 q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1792 384v-384h-1792v384h1792zM1792 896v-384h-1792v384h1792zM1792 1408v-384h-1792v384h1792z" /> -<glyph unicode="" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1664 512h352q13 0 22.5 -9.5t9.5 -22.5v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-352q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5 t-9.5 22.5v352h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v352q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5v-352zM928 288q0 -52 38 -90t90 -38h256v-238q-68 -50 -171 -50h-874q-121 0 -194 69t-73 190q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q79 -61 154.5 -91.5t164.5 -30.5t164.5 30.5t154.5 91.5q20 17 39 17q132 0 217 -96h-223q-52 0 -90 -38t-38 -90v-192z" /> -<glyph unicode="" horiz-adv-x="2048" d="M704 640q-159 0 -271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5t-112.5 -271.5t-271.5 -112.5zM1781 320l249 -249q9 -9 9 -23q0 -13 -9 -22l-136 -136q-9 -9 -22 -9q-14 0 -23 9l-249 249l-249 -249q-9 -9 -23 -9q-13 0 -22 9l-136 136 q-9 9 -9 22q0 14 9 23l249 249l-249 249q-9 9 -9 23q0 13 9 22l136 136q9 9 22 9q14 0 23 -9l249 -249l249 249q9 9 23 9q13 0 22 -9l136 -136q9 -9 9 -22q0 -14 -9 -23zM1283 320l-181 -181q-37 -37 -37 -91q0 -53 37 -90l83 -83q-21 -3 -44 -3h-874q-121 0 -194 69 t-73 190q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q19 0 39 -17q154 -122 319 -122t319 122q20 17 39 17q28 0 57 -6q-28 -27 -41 -50t-13 -56q0 -54 37 -91z" /> -<glyph unicode="" horiz-adv-x="2048" d="M256 512h1728q26 0 45 -19t19 -45v-448h-256v256h-1536v-256h-256v1216q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-704zM832 832q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM2048 576v64q0 159 -112.5 271.5t-271.5 112.5h-704 q-26 0 -45 -19t-19 -45v-384h1152z" /> -<glyph unicode="" d="M1536 1536l-192 -448h192v-192h-274l-55 -128h329v-192h-411l-357 -832l-357 832h-411v192h329l-55 128h-274v192h192l-192 448h256l323 -768h378l323 768h256zM768 320l108 256h-216z" /> -<glyph unicode="" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM768 192q80 0 136 56t56 136t-56 136t-136 56 t-136 -56t-56 -136t56 -136t136 -56zM1344 768v512h-1152v-512h1152z" /> -<glyph unicode="" d="M1088 1536q185 0 316.5 -93.5t131.5 -226.5v-896q0 -130 -125.5 -222t-305.5 -97l213 -202q16 -15 8 -35t-30 -20h-1056q-22 0 -30 20t8 35l213 202q-180 5 -305.5 97t-125.5 222v896q0 133 131.5 226.5t316.5 93.5h640zM288 224q66 0 113 47t47 113t-47 113t-113 47 t-113 -47t-47 -113t47 -113t113 -47zM704 768v512h-544v-512h544zM1248 224q66 0 113 47t47 113t-47 113t-113 47t-113 -47t-47 -113t47 -113t113 -47zM1408 768v512h-576v-512h576z" /> -<glyph unicode="" horiz-adv-x="1792" d="M1792 204v-209h-642v209h134v926h-6l-314 -1135h-243l-310 1135h-8v-926h135v-209h-538v209h69q21 0 43 19.5t22 37.5v881q0 18 -22 40t-43 22h-69v209h672l221 -821h6l223 821h670v-209h-71q-19 0 -41 -22t-22 -40v-881q0 -18 21.5 -37.5t41.5 -19.5h71z" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -<glyph unicode="" horiz-adv-x="1792" /> -</font> -</defs></svg> \ No newline at end of file diff --git a/admin/src/main/resources/static/fonts/fontawesome-webfont.ttf b/admin/src/main/resources/static/fonts/fontawesome-webfont.ttf deleted file mode 100755 index ed9372f8ea0fbaa04f42630a48887e4b38945345..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/admin/src/main/resources/static/fonts/fontawesome-webfont.woff b/admin/src/main/resources/static/fonts/fontawesome-webfont.woff deleted file mode 100755 index 8b280b98fa2fa261aa4b0f8fd061f772073ef83e..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/admin/src/main/resources/static/fonts/fontawesome-webfont.woff2 b/admin/src/main/resources/static/fonts/fontawesome-webfont.woff2 deleted file mode 100755 index 3311d585145b1cc1b9581e914acbb32d8542b4f5..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/admin/src/main/resources/static/images/4.png b/admin/src/main/resources/static/images/4.png deleted file mode 100755 index 7f0c0903ad7ac3179545cd5df77f744b1394b637..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/4.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/Jira2.png b/admin/src/main/resources/static/images/icons/Jira2.png deleted file mode 100755 index da74df0a063d7e7e5d7c4dcb6d671241d0eb289c..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/Jira2.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/Reports-icon.png b/admin/src/main/resources/static/images/icons/Reports-icon.png deleted file mode 100755 index c5fc74c321157353cbfd9fcc2e0212867e292614..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/Reports-icon.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/SOPs.png b/admin/src/main/resources/static/images/icons/SOPs.png deleted file mode 100755 index 3f16d61a59fa54705479976b692e3f26fc6fe6e6..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/SOPs.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/cdp.png b/admin/src/main/resources/static/images/icons/cdp.png deleted file mode 100755 index 57a8ec28478db289c885826e11be28b6b419f535..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/cdp.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/contact.png b/admin/src/main/resources/static/images/icons/contact.png deleted file mode 100755 index ec9aee4644d3c4408428a1efff182a4cf22d27e5..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/contact.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/finder.png b/admin/src/main/resources/static/images/icons/finder.png deleted file mode 100755 index ffaa32f67ff4558aef0ae790a11d159de690b5b2..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/finder.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/github.jpg b/admin/src/main/resources/static/images/icons/github.jpg deleted file mode 100755 index 9b28179d87500d2b9b081b0518923498166092aa..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/github.jpg and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/vms.png b/admin/src/main/resources/static/images/icons/vms.png deleted file mode 100755 index 0fd9e746af102c81df2483a0857d5b2386e302d7..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/vms.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/icons/zoomaa.png b/admin/src/main/resources/static/images/icons/zoomaa.png deleted file mode 100755 index 86a081aa27c4ccc60027d16282759e919f6c8b6f..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/icons/zoomaa.png and /dev/null differ diff --git a/admin/src/main/resources/static/images/profile_small.jpg b/admin/src/main/resources/static/images/profile_small.jpg deleted file mode 100755 index 2446dc8c00e0b30fedabb201976174ea10ed4807..0000000000000000000000000000000000000000 Binary files a/admin/src/main/resources/static/images/profile_small.jpg and /dev/null differ diff --git a/admin/src/main/resources/static/js/bootstrap.min.js b/admin/src/main/resources/static/js/bootstrap.min.js deleted file mode 100755 index e79c065134f2cfcf3e44a59cffcb5f090232f98f..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(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.6",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.6",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")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),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"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||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=null,this.sliding=null,this.interval=null,this.$active=null,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.6",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=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},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=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,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(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),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|hide/.test(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('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][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.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},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.children(".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":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(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 c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}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.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);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(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.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",c).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",".dropdown-menu",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.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,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.6",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.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),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.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$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").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.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(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},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.adjustDialog()},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(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},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;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",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){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");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=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(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.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},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)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(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),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=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",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},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+=g,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=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.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.right&&(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(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},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))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(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),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};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;(e||!/destroy|hide/.test(b))&&(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.6",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")};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){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.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",a.proxy(this.process,this)),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.6",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=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.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]&&(void 0===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.6",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").length&&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=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",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>=e?"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=Math.max(a(document).height(),a(document.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/admin/src/main/resources/static/js/jquery-2.1.1.js b/admin/src/main/resources/static/js/jquery-2.1.1.js deleted file mode 100755 index 9ed2acc66dc4b8573176fe94b636e98799cee014..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/jquery-2.1.1.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.1.1 | (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={},l=a.document,m="2.1.1",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!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));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,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},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: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){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;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&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),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,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=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{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(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 ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(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=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?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!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.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},B=b?function(a,b){if(a===b)return l=!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===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.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=fb.selectors={cacheLength:50,createPseudo:hb,match:X,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(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===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]||fb.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]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(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(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.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(),s=!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&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&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]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)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&&(s&&((l[u]||(l[u]={}))[a]=[w,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()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(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:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?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===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.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 Z.test(a.nodeName)},input:function(a){return Y.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:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(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]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[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?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;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=[w,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[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(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 tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(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 vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(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?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(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 g.call(b,a)>=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=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},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=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.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:l,!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}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,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))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}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=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))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?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):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 D(a,b){while((a=a[b])&&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 D(a,"nextSibling")},prev:function(a){return D(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 a.contentDocument||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&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(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&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};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 H;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){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=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};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),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){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) -},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),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=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(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 L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",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=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.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=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=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(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.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=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(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,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!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(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},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 offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},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=W.test(e)?this.mouseHooks:V.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=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(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=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},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?Z:$):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:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},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}}}),k.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=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(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(g in a)this.on(g,b,c,a[g],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=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.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=$),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}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={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,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(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 kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=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=jb(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=jb(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(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(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(ob(a,!1)),a.textContent="");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 J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(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(ob(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,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.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(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}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=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.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}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),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 zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(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+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(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}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(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;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.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"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[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+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(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 Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,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=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.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):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.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}}},Kb.propHooks.scrollTop=Kb.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=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.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 Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(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++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(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 Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),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:Lb||Sb(),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(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,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(Xb,{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],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.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(S).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=Xb(this,n.extend({},a),f);(e||L.get(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=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.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=L.get(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(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("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=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=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(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=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=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(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===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),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(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),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){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){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===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){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(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(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(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\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(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(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||(k.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--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),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}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),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 cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=l.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;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 tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(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:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,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?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),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(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e: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 c&&c.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||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(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]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=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,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(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){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(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.firstElementChild)a=a.firstElementChild;return a}).append(this)),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},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Bc(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)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},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")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.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(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&"withCredentials"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;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)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),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")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.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(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.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,Gc.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||l;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 Ic=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}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)&&(f+i).indexOf("auto")>-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=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.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 J(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 Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n}); \ No newline at end of file diff --git a/admin/src/main/resources/static/js/pdxAdmin.js b/admin/src/main/resources/static/js/pdxAdmin.js deleted file mode 100755 index 54fa468adf3879891ab663c795ac79a090e76f88..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/pdxAdmin.js +++ /dev/null @@ -1,294 +0,0 @@ - -$(document).ready(function () { - - - // Add body-small class if window less than 768px - if ($(this).width() < 769) { - $('body').addClass('body-small') - } else { - $('body').removeClass('body-small') - } - - // MetsiMenu - $('#side-menu').metisMenu(); - - // Collapse ibox function - $('.collapse-link').click(function () { - var ibox = $(this).closest('div.ibox'); - var button = $(this).find('i'); - var content = ibox.find('div.ibox-content'); - content.slideToggle(200); - button.toggleClass('fa-chevron-up').toggleClass('fa-chevron-down'); - ibox.toggleClass('').toggleClass('border-bottom'); - setTimeout(function () { - ibox.resize(); - ibox.find('[id^=map-]').resize(); - }, 50); - }); - - // Close ibox function - $('.close-link').click(function () { - var content = $(this).closest('div.ibox'); - content.remove(); - }); - - // Fullscreen ibox function - $('.fullscreen-link').click(function () { - var ibox = $(this).closest('div.ibox'); - var button = $(this).find('i'); - $('body').toggleClass('fullscreen-ibox-mode'); - button.toggleClass('fa-expand').toggleClass('fa-compress'); - ibox.toggleClass('fullscreen'); - setTimeout(function () { - $(window).trigger('resize'); - }, 100); - }); - - // Close menu in canvas mode - $('.close-canvas-menu').click(function () { - $("body").toggleClass("mini-navbar"); - SmoothlyMenu(); - }); - - // Run menu of canvas - $('body.canvas-menu .sidebar-collapse').slimScroll({ - height: '100%', - railOpacity: 0.9 - }); - - // Open close right sidebar - $('.right-sidebar-toggle').click(function () { - $('#right-sidebar').toggleClass('sidebar-open'); - }); - - // Initialize slimscroll for right sidebar - $('.sidebar-container').slimScroll({ - height: '100%', - railOpacity: 0.4, - wheelStep: 10 - }); - - // Open close small chat - $('.open-small-chat').click(function () { - $(this).children().toggleClass('fa-comments').toggleClass('fa-remove'); - $('.small-chat-box').toggleClass('active'); - }); - - // Initialize slimscroll for small chat - $('.small-chat-box .content').slimScroll({ - height: '234px', - railOpacity: 0.4 - }); - - // Small todo handler - $('.check-link').click(function () { - var button = $(this).find('i'); - var label = $(this).next('span'); - button.toggleClass('fa-check-square').toggleClass('fa-square-o'); - label.toggleClass('todo-completed'); - return false; - }); - - // Append config box / Only for demo purpose - // Uncomment on server mode to enable XHR calls - //$.get("skin-config.html", function (data) { - // if (!$('body').hasClass('no-skin-config')) - // $('body').append(data); - //}); - - // Minimalize menu - $('.navbar-minimalize').click(function () { - $("body").toggleClass("mini-navbar"); - SmoothlyMenu(); - - }); - - // Tooltips demo - $('.tooltip-demo').tooltip({ - selector: "[data-toggle=tooltip]", - container: "body" - }); - - // Move modal to body - // Fix Bootstrap backdrop issu with animation.css - $('.modal').appendTo("body"); - - // Full height of sidebar - function fix_height() { - var heightWithoutNavbar = $("body > #wrapper").height() - 61; - $(".sidebard-panel").css("min-height", heightWithoutNavbar + "px"); - - var navbarHeigh = $('nav.navbar-default').height(); - var wrapperHeigh = $('#page-wrapper').height(); - - if (navbarHeigh > wrapperHeigh) { - $('#page-wrapper').css("min-height", navbarHeigh + "px"); - } - - if (navbarHeigh < wrapperHeigh) { - $('#page-wrapper').css("min-height", $(window).height() + "px"); - } - - if ($('body').hasClass('fixed-nav')) { - if (navbarHeigh > wrapperHeigh) { - $('#page-wrapper').css("min-height", navbarHeigh - 60 + "px"); - } else { - $('#page-wrapper').css("min-height", $(window).height() - 60 + "px"); - } - } - - } - - fix_height(); - - // Fixed Sidebar - $(window).bind("load", function () { - if ($("body").hasClass('fixed-sidebar')) { - $('.sidebar-collapse').slimScroll({ - height: '100%', - railOpacity: 0.9 - }); - } - }); - - // Move right sidebar top after scroll - $(window).scroll(function () { - if ($(window).scrollTop() > 0 && !$('body').hasClass('fixed-nav')) { - $('#right-sidebar').addClass('sidebar-top'); - } else { - $('#right-sidebar').removeClass('sidebar-top'); - } - }); - - $(window).bind("load resize scroll", function () { - if (!$("body").hasClass('body-small')) { - fix_height(); - } - }); - - $("[data-toggle=popover]") - .popover(); - - // Add slimscroll to element - $('.full-height-scroll').slimscroll({ - height: '100%' - }) -}); - - -// Minimalize menu when screen is less than 768px -$(window).bind("resize", function () { - if ($(this).width() < 769) { - $('body').addClass('body-small') - } else { - $('body').removeClass('body-small') - } -}); - -// Local Storage functions -// Set proper body class and plugins based on user configuration -$(document).ready(function () { - if (localStorageSupport) { - - var collapse = localStorage.getItem("collapse_menu"); - var fixedsidebar = localStorage.getItem("fixedsidebar"); - var fixednavbar = localStorage.getItem("fixednavbar"); - var boxedlayout = localStorage.getItem("boxedlayout"); - var fixedfooter = localStorage.getItem("fixedfooter"); - - var body = $('body'); - - if (fixedsidebar == 'on') { - body.addClass('fixed-sidebar'); - $('.sidebar-collapse').slimScroll({ - height: '100%', - railOpacity: 0.9 - }); - } - - if (collapse == 'on') { - if (body.hasClass('fixed-sidebar')) { - if (!body.hasClass('body-small')) { - body.addClass('mini-navbar'); - } - } else { - if (!body.hasClass('body-small')) { - body.addClass('mini-navbar'); - } - - } - } - - if (fixednavbar == 'on') { - $(".navbar-static-top").removeClass('navbar-static-top').addClass('navbar-fixed-top'); - body.addClass('fixed-nav'); - } - - if (boxedlayout == 'on') { - body.addClass('boxed-layout'); - } - - if (fixedfooter == 'on') { - $(".footer").addClass('fixed'); - } - } -}); - -// check if browser support HTML5 local storage -function localStorageSupport() { - return (('localStorage' in window) && window['localStorage'] !== null) -} - -// For demo purpose - animation css script -function animationHover(element, animation) { - element = $(element); - element.hover( - function () { - element.addClass('animated ' + animation); - }, - function () { - //wait for animation to finish before removing classes - window.setTimeout(function () { - element.removeClass('animated ' + animation); - }, 2000); - }); -} - -function SmoothlyMenu() { - if (!$('body').hasClass('mini-navbar') || $('body').hasClass('body-small')) { - // Hide menu in order to smoothly turn on when maximize menu - $('#side-menu').hide(); - // For smoothly turn on menu - setTimeout( - function () { - $('#side-menu').fadeIn(400); - }, 200); - } else if ($('body').hasClass('fixed-sidebar')) { - $('#side-menu').hide(); - setTimeout( - function () { - $('#side-menu').fadeIn(400); - }, 100); - } else { - // Remove all inline style from jquery fadeIn function to reset menu state - $('#side-menu').removeAttr('style'); - } -} - -// Dragable panels -function WinMove() { - var element = "[class*=col]"; - var handle = ".ibox-title"; - var connect = "[class*=col]"; - $(element).sortable( - { - handle: handle, - connectWith: connect, - tolerance: 'pointer', - forcePlaceholderSize: true, - opacity: 0.8 - }) - .disableSelection(); -} - - diff --git a/admin/src/main/resources/static/js/plugins/chart/3dbar.js b/admin/src/main/resources/static/js/plugins/chart/3dbar.js deleted file mode 100755 index 27836c1a21563740a4df0f7587dd5f8db0205d9b..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/3dbar.js +++ /dev/null @@ -1,110 +0,0 @@ -var chart = AmCharts.makeChart("chartdiv", { - "theme": "light", - "type": "serial", - "startDuration": 2, - "dataProvider": [{ - "country": "Breast Cancer", - "visits": 4025, - "color": "#FF0F00" - }, { - "country": "Pancreatic", - "visits": 1882, - "color": "#FF6600" - }, { - "country": "Rectum", - "visits": 1809, - "color": "#FF9E01" - }, { - "country": "Bile Duct", - "visits": 1322, - "color": "#FCD202" - }, { - "country": "Liver", - "visits": 1122, - "color": "#F8FF01" - }, { - "country": "Salivary Gland", - "visits": 1114, - "color": "#B0DE09" - }, { - "country": "tonsil", - "visits": 984, - "color": "#04D215" - }, { - "country": "anal", - "visits": 711, - "color": "#0D8ECF" - }, { - "country": "Stomach", - "visits": 665, - "color": "#0D52D1" - }, { - "country": "appendix", - "visits": 580, - "color": "#2A0CD0" - }, { - "country": "esophageal", - "visits": 443, - "color": "#8A0CCF" - }, { - "country": "duodenum", - "visits": 441, - "color": "#CD0D74" - }, { - "country": "lung ", - "visits": 395, - "color": "#754DEB" - }, { - "country": "Brain", - "visits": 386, - "color": "#DDDDDD" - }, { - "country": "adrenal gland", - "visits": 384, - "color": "#999999" - }, { - "country": "Breast", - "visits": 338, - "color": "#333333" - }, { - "country": "Skin", - "visits": 328, - "color": "#000000" - }], - "valueAxes": [{ - "position": "left", - "title": "Visitors" - }], - "graphs": [{ - "balloonText": "[[category]]: <b>[[value]]</b>", - "fillColorsField": "color", - "fillAlphas": 1, - "lineAlpha": 0.1, - "type": "column", - "valueField": "visits", - "showHandOnHover": true - }], - "depth3D": 20, - "angle": 30, - "chartCursor": { - "categoryBalloonEnabled": false, - "cursorAlpha": 0, - "zoomable": true - }, - "categoryField": "country", - "categoryAxis": { - "gridPosition": "start", - "labelRotation": 0 - }, - "listeners": [{ - "event": "clickGraphItem", - "method": function(event) { - var drillDownLink = 'http://www.pdxfinder.org/data/search?cancer_system='+event.item.category; - window.open(drillDownLink,'_blank'); - } - }], - "export": { - "enabled": true - } - -}); \ No newline at end of file diff --git a/admin/src/main/resources/static/js/plugins/chart/amcharts.js b/admin/src/main/resources/static/js/plugins/chart/amcharts.js deleted file mode 100755 index 0b5e4944311fdf82e33471174ad34fe8da182fb5..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/amcharts.js +++ /dev/null @@ -1,55 +0,0 @@ -(function(){var d;window.AmCharts?d=window.AmCharts:(d={},window.AmCharts=d,d.themes={},d.maps={},d.inheriting={},d.charts=[],d.onReadyArray=[],d.useUTC=!1,d.updateRate=60,d.uid=0,d.lang={},d.translations={},d.mapTranslations={},d.windows={},d.initHandlers=[],d.amString="am",d.pmString="pm");d.Class=function(a){var b=function(){arguments[0]!==d.inheriting&&(this.events={},this.construct.apply(this,arguments))};a.inherits?(b.prototype=new a.inherits(d.inheriting),b.base=a.inherits.prototype,delete a.inherits):(b.prototype.createEvents=function(){for(var a=0;a<arguments.length;a++)this.events[arguments[a]]=[]},b.prototype.listenTo=function(a,b,c){this.removeListener(a,b,c);a.events[b].push({handler:c,scope:this})},b.prototype.addListener=function(a,b,c){this.removeListener(this,a,b);a&&this.events[a]&&this.events[a].push({handler:b,scope:c})},b.prototype.removeListener=function(a,b,c){if(a&&a.events&&(a=a.events[b]))for(b=a.length-1;0<=b;b--)a[b].handler===c&&a.splice(b,1)},b.prototype.fire=function(a){for(var b=this.events[a.type],c=0;c<b.length;c++){var d=b[c];d.handler.call(d.scope,a)}});for(var c in a)b.prototype[c]=a[c];return b};d.addChart=function(a){window.requestAnimationFrame?d.animationRequested||(d.animationRequested=!0,window.requestAnimationFrame(d.update)):d.updateInt||(d.updateInt=setInterval(function(){d.update()},Math.round(1E3/d.updateRate)));d.charts.push(a)};d.removeChart=function(a){for(var b=d.charts,c=b.length-1;0<=c;c--)b[c]==a&&b.splice(c,1);0===b.length&&(d.requestAnimation&&(window.cancelAnimationFrame(d.requestAnimation),d.animationRequested=!1),d.updateInt&&(clearInterval(d.updateInt),d.updateInt=NaN))};d.isModern=!0;d.getIEVersion=function(){var a=0,b,c;"Microsoft Internet Explorer"==navigator.appName&&(b=navigator.userAgent,c=/MSIE ([0-9]{1,}[.0-9]{0,})/,null!==c.exec(b)&&(a=parseFloat(RegExp.$1)));return a};d.applyLang=function(a,b){var c=d.translations;b.dayNames=d.extend({},d.dayNames);b.shortDayNames=d.extend({},d.shortDayNames);b.monthNames=d.extend({},d.monthNames);b.shortMonthNames=d.extend({},d.shortMonthNames);b.amString="am";b.pmString="pm";c&&(c=c[a])&&(d.lang=c,b.langObj=c,c.monthNames&&(b.dayNames=d.extend({},c.dayNames),b.shortDayNames=d.extend({},c.shortDayNames),b.monthNames=d.extend({},c.monthNames),b.shortMonthNames=d.extend({},c.shortMonthNames)),c.am&&(b.amString=c.am),c.pm&&(b.pmString=c.pm));d.amString=b.amString;d.pmString=b.pmString};d.IEversion=d.getIEVersion();9>d.IEversion&&0<d.IEversion&&(d.isModern=!1,d.isIE=!0);d.dx=0;d.dy=0;if(document.addEventListener||window.opera)d.isNN=!0,d.isIE=!1,d.dx=.5,d.dy=.5;document.attachEvent&&(d.isNN=!1,d.isIE=!0,d.isModern||(d.dx=0,d.dy=0));window.chrome&&(d.chrome=!0);d.handleMouseUp=function(a){for(var b=d.charts,c=0;c<b.length;c++){var e=b[c];e&&e.handleReleaseOutside&&e.handleReleaseOutside(a)}};d.handleMouseMove=function(a){for(var b=d.charts,c=0;c<b.length;c++){var e=b[c];e&&e.handleMouseMove&&e.handleMouseMove(a)}};d.handleWheel=function(a){for(var b=d.charts,c=0;c<b.length;c++){var e=b[c];if(e&&e.mouseIsOver){(e.mouseWheelScrollEnabled||e.mouseWheelZoomEnabled)&&e.handleWheel&&e.handleWheel(a);break}}};d.resetMouseOver=function(){for(var a=d.charts,b=0;b<a.length;b++){var c=a[b];c&&(c.mouseIsOver=!1)}};d.ready=function(a){d.onReadyArray.push(a)};d.handleLoad=function(){d.isReady=!0;for(var a=d.onReadyArray,b=0;b<a.length;b++){var c=a[b];isNaN(d.processDelay)?c():setTimeout(c,d.processDelay*b)}d.onReadyArray=[]};d.addInitHandler=function(a,b){d.initHandlers.push({method:a,types:b})};d.callInitHandler=function(a){var b=d.initHandlers;if(d.initHandlers)for(var c=0;c<b.length;c++){var e=b[c];e.types?d.isInArray(e.types,a.type)&&e.method(a):e.method(a)}};d.getUniqueId=function(){d.uid++;return"AmChartsEl-"+d.uid};d.isNN&&(document.addEventListener("mousemove",d.handleMouseMove),document.addEventListener("mouseup",d.handleMouseUp,!0),window.addEventListener("load",d.handleLoad,!0));d.isIE&&(document.attachEvent("onmousemove",d.handleMouseMove),document.attachEvent("onmouseup",d.handleMouseUp),window.attachEvent("onload",d.handleLoad));d.addWheelListeners=function(){d.wheelIsListened||(d.isNN&&(window.addEventListener("DOMMouseScroll",d.handleWheel,!0),document.addEventListener("mousewheel",d.handleWheel,!0)),d.isIE&&document.attachEvent("onmousewheel",d.handleWheel));d.wheelIsListened=!0};d.clear=function(){var a=d.charts;if(a)for(var b=a.length-1;0<=b;b--)a[b].clear();d.updateInt&&clearInterval(d.updateInt);d.requestAnimation&&window.cancelAnimationFrame(d.requestAnimation);d.charts=[];d.isNN&&(document.removeEventListener("mousemove",d.handleMouseMove,!0),document.removeEventListener("mouseup",d.handleMouseUp,!0),window.removeEventListener("load",d.handleLoad,!0),window.removeEventListener("DOMMouseScroll",d.handleWheel,!0),document.removeEventListener("mousewheel",d.handleWheel,!0));d.isIE&&(document.detachEvent("onmousemove",d.handleMouseMove),document.detachEvent("onmouseup",d.handleMouseUp),window.detachEvent("onload",d.handleLoad))};d.makeChart=function(a,b,c){var e=b.type,h=b.theme;d.isString(h)&&(h=d.themes[h],b.theme=h);var f;switch(e){case"serial":f=new d.AmSerialChart(h);break;case"xy":f=new d.AmXYChart(h);break;case"pie":f=new d.AmPieChart(h);break;case"radar":f=new d.AmRadarChart(h);break;case"gauge":f=new d.AmAngularGauge(h);break;case"funnel":f=new d.AmFunnelChart(h);break;case"map":f=new d.AmMap(h);break;case"stock":f=new d.AmStockChart(h);break;case"gantt":f=new d.AmGanttChart(h)}d.extend(f,b);d.isReady?isNaN(c)?f.write(a):setTimeout(function(){d.realWrite(f,a)},c):d.ready(function(){isNaN(c)?f.write(a):setTimeout(function(){d.realWrite(f,a)},c)});return f};d.realWrite=function(a,b){a.write(b)};d.updateCount=0;d.validateAt=Math.round(d.updateRate/10);d.update=function(){var a=d.charts;d.updateCount++;var b=!1;d.updateCount==d.validateAt&&(b=!0,d.updateCount=0);if(a)for(var c=a.length-1;0<=c;c--)a[c].update&&a[c].update(),b&&(a[c].autoResize?a[c].validateSize&&a[c].validateSize():a[c].premeasure&&a[c].premeasure());window.requestAnimationFrame&&(d.requestAnimation=window.requestAnimationFrame(d.update))};"complete"==document.readyState&&d.handleLoad()})();(function(){var d=window.AmCharts;d.toBoolean=function(a,b){if(void 0===a)return b;switch(String(a).toLowerCase()){case"true":case"yes":case"1":return!0;case"false":case"no":case"0":case null:return!1;default:return!!a}};d.removeFromArray=function(a,b){var c;if(void 0!==b&&void 0!==a)for(c=a.length-1;0<=c;c--)a[c]==b&&a.splice(c,1)};d.getPath=function(){var a=document.getElementsByTagName("script");if(a)for(var b=0;b<a.length;b++){var c=a[b].src;if(-1!==c.search(/\/(amcharts|ammap)\.js/))return c.replace(/\/(amcharts|ammap)\.js.*/,"/")}};d.normalizeUrl=function(a){return""!==a&&-1===a.search(/\/$/)?a+"/":a};d.isAbsolute=function(a){return 0===a.search(/^http[s]?:|^\//)};d.isInArray=function(a,b){for(var c=0;c<a.length;c++)if(a[c]==b)return!0;return!1};d.getDecimals=function(a){var b=0;isNaN(a)||(a=String(a),-1!=a.indexOf("e-")?b=Number(a.split("-")[1]):-1!=a.indexOf(".")&&(b=a.split(".")[1].length));return b};d.wordwrap=function(a,b,c,e){var h,f,g,k;a+="";if(1>b)return a;h=-1;for(a=(k=a.split(/\r\n|\n|\r/)).length;++h<a;k[h]+=g){g=k[h];for(k[h]="";g.length>b;k[h]+=d.trim(g.slice(0,f))+((g=g.slice(f)).length?c:""))f=2==e||(f=g.slice(0,b+1).match(/\S*(\s)?$/))[1]?b:f.input.length-f[0].length||1==e&&b||f.input.length+(f=g.slice(b).match(/^\S*/))[0].length;g=d.trim(g)}return k.join(c)};d.trim=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};d.wrappedText=function(a,b,c,e,h,f,g,k){var l=d.text(a,b,c,e,h,f,g);if(l){var m=l.getBBox();if(m.width>k){var p="\n";d.isModern||(p="<br>");k=Math.floor(k/(m.width/ -b.length));2<k&&(k-=2);b=d.wordwrap(b,k,p,!0);l.remove();l=d.text(a,b,c,e,h,f,g)}}return l};d.getStyle=function(a,b){var c="";if(document.defaultView&&document.defaultView.getComputedStyle)try{c=document.defaultView.getComputedStyle(a,"").getPropertyValue(b)}catch(e){}else a.currentStyle&&(b=b.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),c=a.currentStyle[b]);return c};d.removePx=function(a){if(void 0!==a)return Number(a.substring(0,a.length-2))};d.getURL=function(a,b){if(a)if("_self"!=b&&b)if("_top"==b&&window.top)window.top.location.href=a;else if("_parent"==b&&window.parent)window.parent.location.href=a;else if("_blank"==b)window.open(a);else{var c=document.getElementsByName(b)[0];c?c.src=a:(c=d.windows[b])?c.opener&&!c.opener.closed?c.location.href=a:d.windows[b]=window.open(a):d.windows[b]=window.open(a)}else window.location.href=a};d.ifArray=function(a){return a&&"object"==typeof a&&0<a.length?!0:!1};d.callMethod=function(a,b){var c;for(c=0;c<b.length;c++){var e=b[c];if(e){if(e[a])e[a]();var d=e.length;if(0<d){var f;for(f=0;f<d;f++){var g=e[f];if(g&&g[a])g[a]()}}}}};d.toNumber=function(a){return"number"==typeof a?a:Number(String(a).replace(/[^0-9\-.]+/g,""))};d.toColor=function(a){if(""!==a&&void 0!==a)if(-1!=a.indexOf(",")){a=a.split(",");var b;for(b=0;b<a.length;b++){var c=a[b].substring(a[b].length-6,a[b].length);a[b]="#"+c}}else a=a.substring(a.length-6,a.length),a="#"+a;return a};d.toCoordinate=function(a,b,c){var e;void 0!==a&&(a=String(a),c&&c<b&&(b=c),e=Number(a),-1!=a.indexOf("!")&&(e=b-Number(a.substr(1))),-1!=a.indexOf("%")&&(e=b*Number(a.substr(0,a.length-1))/100));return e};d.fitToBounds=function(a,b,c){a<b&&(a=b);a>c&&(a=c);return a};d.isDefined=function(a){return void 0===a?!1:!0};d.stripNumbers=function(a){return a.replace(/[0-9]+/g,"")};d.roundTo=function(a,b){if(0>b)return a;var c=Math.pow(10,b);return Math.round(a*c)/c};d.toFixed=function(a,b){var c=!1;0>a&&(c=!0,a=Math.abs(a));var e=String(Math.round(a*Math.pow(10,b)));if(0<b){var d=e.length;if(d<b){var f;for(f=0;f< -b-d;f++)e="0"+e}d=e.substring(0,e.length-b);""===d&&(d=0);e=d+"."+e.substring(e.length-b,e.length);return c?"-"+e:e}return String(e)};d.formatDuration=function(a,b,c,e,h,f){var g=d.intervals,k=f.decimalSeparator;if(a>=g[b].contains){var l=a-Math.floor(a/g[b].contains)*g[b].contains;"ss"==b?(l=d.formatNumber(l,f),1==l.split(k)[0].length&&(l="0"+l)):l=d.roundTo(l,f.precision);("mm"==b||"hh"==b)&&10>l&&(l="0"+l);c=l+""+e[b]+""+c;a=Math.floor(a/g[b].contains);b=g[b].nextInterval;return d.formatDuration(a,b,c,e,h,f)}"ss"==b&&(a=d.formatNumber(a,f),1==a.split(k)[0].length&&(a="0"+a));("mm"==b||"hh"==b)&&10>a&&(a="0"+a);c=a+""+e[b]+""+c;if(g[h].count>g[b].count)for(a=g[b].count;a<g[h].count;a++)b=g[b].nextInterval,"ss"==b||"mm"==b||"hh"==b?c="00"+e[b]+""+c:"DD"==b&&(c="0"+e[b]+""+c);":"==c.charAt(c.length-1)&&(c=c.substring(0,c.length-1));return c};d.formatNumber=function(a,b,c,e,h){a=d.roundTo(a,b.precision);isNaN(c)&&(c=b.precision);var f=b.decimalSeparator;b=b.thousandsSeparator;var g;g=0>a?"-":"";a=Math.abs(a);var k=String(a),l=!1;-1!=k.indexOf("e")&&(l=!0);0<=c&&!l&&(k=d.toFixed(a,c));var m="";if(l)m=k;else{var k=k.split("."),l=String(k[0]),p;for(p=l.length;0<=p;p-=3)m=p!=l.length?0!==p?l.substring(p-3,p)+b+m:l.substring(p-3,p)+m:l.substring(p-3,p);void 0!==k[1]&&(m=m+f+k[1]);void 0!==c&&0<c&&"0"!=m&&(m=d.addZeroes(m,f,c))}m=g+m;""===g&&!0===e&&0!==a&&(m="+"+m);!0===h&&(m+="%");return m};d.addZeroes=function(a,b,c){a=a.split(b);void 0===a[1]&&0<c&&(a[1]="0");return a[1].length<c?(a[1]+="0",d.addZeroes(a[0]+b+a[1],b,c)):void 0!==a[1]?a[0]+b+a[1]:a[0]};d.scientificToNormal=function(a){var b;a=String(a).split("e");var c;if("-"==a[1].substr(0,1)){b="0.";for(c=0;c<Math.abs(Number(a[1]))-1;c++)b+="0";b+=a[0].split(".").join("")}else{var e=0;b=a[0].split(".");b[1]&&(e=b[1].length);b=a[0].split(".").join("");for(c=0;c<Math.abs(Number(a[1]))-e;c++)b+="0"}return b};d.toScientific=function(a,b){if(0===a)return"0";var c=Math.floor(Math.log(Math.abs(a))*Math.LOG10E),e=String(e).split(".").join(b);return String(e)+"e"+c};d.randomColor=function(){return"#"+("00000"+(16777216*Math.random()<<0).toString(16)).substr(-6)};d.hitTest=function(a,b,c){var e=!1,h=a.x,f=a.x+a.width,g=a.y,k=a.y+a.height,l=d.isInRectangle;e||(e=l(h,g,b));e||(e=l(h,k,b));e||(e=l(f,g,b));e||(e=l(f,k,b));e||!0===c||(e=d.hitTest(b,a,!0));return e};d.isInRectangle=function(a,b,c){return a>=c.x-5&&a<=c.x+c.width+5&&b>=c.y-5&&b<=c.y+c.height+5?!0:!1};d.isPercents=function(a){if(-1!=String(a).indexOf("%"))return!0};d.formatValue=function(a,b,c,e,h,f,g,k){if(b){void 0===h&&(h="");var l;for(l=0;l<c.length;l++){var m=c[l],p=b[m];void 0!==p&&(p=f?d.addPrefix(p,k,g,e):d.formatNumber(p,e),a=a.replace(new RegExp("\\[\\["+h+""+m+"\\]\\]","g"),p))}}return a};d.formatDataContextValue=function(a,b){if(a){var c=a.match(/\[\[.*?\]\]/g),e;for(e=0;e<c.length;e++){var d=c[e],d=d.substr(2,d.length-4);void 0!==b[d]&&(a=a.replace(new RegExp("\\[\\["+d+"\\]\\]","g"),b[d]))}}return a};d.massReplace=function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var e=b[c];void 0===e&&(e="");a=a.replace(c,e)}return a};d.cleanFromEmpty=function(a){return a.replace(/\[\[[^\]]*\]\]/g,"")};d.addPrefix=function(a,b,c,e,h){var f=d.formatNumber(a,e),g="",k,l,m;if(0===a)return"0";0>a&&(g="-");a=Math.abs(a);if(1<a)for(k=b.length-1;-1<k;k--){if(a>=b[k].number&&(l=a/b[k].number,m=Number(e.precision),1>m&&(m=1),c=d.roundTo(l,m),m=d.formatNumber(c,{precision:-1,decimalSeparator:e.decimalSeparator,thousandsSeparator:e.thousandsSeparator}),!h||l==c)){f=g+""+m+""+b[k].prefix;break}}else for(k=0;k<c.length;k++)if(a<=c[k].number){l=a/c[k].number;m=Math.abs(Math.floor(Math.log(l)*Math.LOG10E));l=d.roundTo(l,m);f=g+""+l+""+c[k].prefix;break}return f};d.remove=function(a){a&&a.remove()};d.getEffect=function(a){">"==a&&(a="easeOutSine");"<"==a&&(a="easeInSine");"elastic"==a&&(a="easeOutElastic");return a};d.getObjById=function(a,b){var c,e;for(e=0;e<a.length;e++){var d=a[e];if(d.id==b){c=d;break}}return c};d.applyTheme=function(a,b,c){b||(b=d.theme);try{b=JSON.parse(JSON.stringify(b))}catch(e){}b&&b[c]&&d.extend(a,b[c])};d.isString=function(a){return"string"==typeof a?!0:!1};d.extend=function(a,b,c){var e;a||(a={});for(e in b)c?a.hasOwnProperty(e)||(a[e]=b[e]):a[e]=b[e];return a};d.copyProperties=function(a,b){for(var c in a)a.hasOwnProperty(c)&&"events"!=c&&void 0!==a[c]&&"function"!=typeof a[c]&&"cname"!=c&&(b[c]=a[c])};d.processObject=function(a,b,c,e){if(!1===a instanceof b&&(a=e?d.extend(new b(c),a):d.extend(a,new b(c),!0),a.listeners))for(var h in a.listeners)b=a.listeners[h],a.addListener(b.event,b.method);return a};d.fixNewLines=function(a){var b=RegExp("\\n","g");a&&(a=a.replace(b,"<br />"));return a};d.fixBrakes=function(a){if(d.isModern){var b=RegExp("<br>","g");a&&(a=a.replace(b,"\n"))}else a=d.fixNewLines(a);return a};d.deleteObject=function(a,b){if(a){if(void 0===b||null===b)b=20;if(0!==b)if("[object Array]"===Object.prototype.toString.call(a))for(var c=0;c<a.length;c++)d.deleteObject(a[c],b-1),a[c]=null;else if(a&&!a.tagName)try{for(c in a.theme=null,a)a[c]&&("object"==typeof a[c]&&d.deleteObject(a[c],b-1),"function"!=typeof a[c]&&(a[c]=null))}catch(e){}}};d.bounce=function(a,b,c,e,d){return(b/=d)<1/2.75?7.5625*e*b*b+c:b<2/2.75?e*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?e*(7.5625*(b-=2.25/2.75)*b+.9375)+c:e*(7.5625*(b-=2.625/2.75)*b+.984375)+c};d.easeInOutQuad=function(a,b,c,e,d){b/=d/2;if(1>b)return e/2*b*b+c;b--;return-e/2*(b*(b-2)-1)+c};d.easeInSine=function(a,b,c,e,d){return-e*Math.cos(b/d*(Math.PI/2))+e+c};d.easeOutSine=function(a,b,c,e,d){return e*Math.sin(b/d*(Math.PI/ -2))+c};d.easeOutElastic=function(a,b,c,e,d){a=1.70158;var f=0,g=e;if(0===b)return c;if(1==(b/=d))return c+e;f||(f=.3*d);g<Math.abs(e)?(g=e,a=f/4):a=f/(2*Math.PI)*Math.asin(e/g);return g*Math.pow(2,-10*b)*Math.sin(2*(b*d-a)*Math.PI/f)+e+c};d.fixStepE=function(a){a=a.toExponential(0).split("e");var b=Number(a[1]);9==Number(a[0])&&b++;return d.generateNumber(1,b)};d.generateNumber=function(a,b){var c="",e;e=0>b?Math.abs(b)-1:Math.abs(b);var d;for(d=0;d<e;d++)c+="0";return 0>b?Number("0."+c+String(a)):Number(String(a)+c)};d.setCN=function(a,b,c,e){if(a.addClassNames&&b&&(b=b.node)&&c){var d=b.getAttribute("class");a=a.classNamePrefix+"-";e&&(a="");d?b.setAttribute("class",d+" "+a+c):b.setAttribute("class",a+c)}};d.removeCN=function(a,b,c){b&&(b=b.node)&&c&&(b=b.classList)&&b.remove(a.classNamePrefix+"-"+c)};d.parseDefs=function(a,b){for(var c in a){var e=typeof a[c];if(0<a[c].length&&"object"==e)for(var h=0;h<a[c].length;h++)e=document.createElementNS(d.SVG_NS,c),b.appendChild(e),d.parseDefs(a[c][h],e);else"object"==e?(e=document.createElementNS(d.SVG_NS,c),b.appendChild(e),d.parseDefs(a[c],e)):b.setAttribute(c,a[c])}}})();(function(){var d=window.AmCharts;d.AxisBase=d.Class({construct:function(a){this.createEvents("clickItem","rollOverItem","rollOutItem","rollOverGuide","rollOutGuide","clickGuide");this.titleDY=this.y=this.x=this.dy=this.dx=0;this.axisThickness=1;this.axisColor="#000000";this.axisAlpha=1;this.gridCount=this.tickLength=5;this.gridAlpha=.15;this.gridThickness=1;this.gridColor="#000000";this.dashLength=0;this.labelFrequency=1;this.showLastLabel=this.showFirstLabel=!0;this.fillColor="#FFFFFF";this.fillAlpha=0;this.labelsEnabled=!0;this.labelRotation=0;this.autoGridCount=!0;this.offset=0;this.guides=[];this.visible=!0;this.counter=0;this.guides=[];this.ignoreAxisWidth=this.inside=!1;this.minHorizontalGap=75;this.minVerticalGap=35;this.titleBold=!0;this.minorGridEnabled=!1;this.minorGridAlpha=.07;this.autoWrap=!1;this.titleAlign="middle";this.labelOffset=0;this.bcn="axis-";this.centerLabels=!1;this.firstDayOfWeek=1;this.centerLabelOnFullPeriod=this.markPeriodChange=this.boldPeriodBeginning=!0;this.periods=[{period:"fff",count:1},{period:"fff",count:5},{period:"fff",count:10},{period:"fff",count:50},{period:"fff",count:100},{period:"fff",count:500},{period:"ss",count:1},{period:"ss",count:5},{period:"ss",count:10},{period:"ss",count:30},{period:"mm",count:1},{period:"mm",count:5},{period:"mm",count:10},{period:"mm",count:30},{period:"hh",count:1},{period:"hh",count:3},{period:"hh",count:6},{period:"hh",count:12},{period:"DD",count:1},{period:"DD",count:2},{period:"DD",count:3},{period:"DD",count:4},{period:"DD",count:5},{period:"WW",count:1},{period:"MM",count:1},{period:"MM",count:2},{period:"MM",count:3},{period:"MM",count:6},{period:"YYYY",count:1},{period:"YYYY",count:2},{period:"YYYY",count:5},{period:"YYYY",count:10},{period:"YYYY",count:50},{period:"YYYY",count:100}];this.dateFormats=[{period:"fff",format:"NN:SS.QQQ"},{period:"ss",format:"JJ:NN:SS"},{period:"mm",format:"JJ:NN"},{period:"hh",format:"JJ:NN"},{period:"DD",format:"MMM DD"},{period:"WW",format:"MMM DD"},{period:"MM",format:"MMM"},{period:"YYYY",format:"YYYY"}];this.nextPeriod={fff:"ss",ss:"mm",mm:"hh",hh:"DD",DD:"MM",MM:"YYYY"};d.applyTheme(this,a,"AxisBase")},zoom:function(a,b){this.start=a;this.end=b;this.dataChanged=!0;this.draw()},fixAxisPosition:function(){var a=this.position;"H"==this.orientation?("left"==a&&(a="bottom"),"right"==a&&(a="top")):("bottom"==a&&(a="left"),"top"==a&&(a="right"));this.position=a},init:function(){this.createBalloon()},draw:function(){var a=this.chart;this.prevBY=this.prevBX=NaN;this.allLabels=[];this.counter=0;this.destroy();this.fixAxisPosition();this.setBalloonBounds();this.labels=[];var b=a.container,c=b.set();a.gridSet.push(c);this.set=c;b=b.set();a.axesLabelsSet.push(b);this.labelsSet=b;this.axisLine=new this.axisRenderer(this);this.autoGridCount?("V"==this.orientation?(a=this.height/this.minVerticalGap,3>a&&(a=3)):a=this.width/this.minHorizontalGap,this.gridCountR=Math.max(a,1)):this.gridCountR=this.gridCount;this.axisWidth=this.axisLine.axisWidth;this.addTitle()},setOrientation:function(a){this.orientation=a?"H":"V"},addTitle:function(){var a=this.title;this.titleLabel=null;if(a){var b=this.chart,c=this.titleColor;void 0===c&&(c=b.color);var e=this.titleFontSize;isNaN(e)&&(e=b.fontSize+1);a=d.text(b.container,a,c,b.fontFamily,e,this.titleAlign,this.titleBold);d.setCN(b,a,this.bcn+"title");this.titleLabel=a}},positionTitle:function(){var a=this.titleLabel;if(a){var b,c,e=this.labelsSet,h={};0<e.length()?h=e.getBBox():(h.x=0,h.y=0,h.width=this.width,h.height=this.height,d.VML&&(h.y+=this.y,h.x+=this.x));e.push(a);var e=h.x,f=h.y;d.VML&&(f-=this.y,e-=this.x);var g=h.width,h=h.height,k=this.width,l=this.height,m=0,p=a.getBBox().height/2,q=this.inside,n=this.titleAlign;switch(this.position){case"top":b="left"==n?-1:"right"==n?k:k/2;c=f-10-p;break;case"bottom":b="left"==n?-1:"right"==n?k:k/2;c=f+h+10+p;break;case"left":b=e-10-p;q&&(b-=5);m=-90;c=("left"==n?l+1:"right"==n?-1:l/2)+this.titleDY;break;case"right":b=e+g+10+p,q&&(b+=7),c=("left"==n?l+2:"right"==n?-2:l/2)+this.titleDY,m=-90}this.marginsChanged?(a.translate(b,c),this.tx=b,this.ty=c):a.translate(this.tx,this.ty);this.marginsChanged=!1;isNaN(this.titleRotation)||(m=this.titleRotation);0!==m&&a.rotate(m)}},pushAxisItem:function(a,b){var c=this,e=a.graphics();0<e.length()&&(b?c.labelsSet.push(e):c.set.push(e));if(e=a.getLabel())c.labelsSet.push(e),e.click(function(b){c.handleMouse(b,a,"clickItem")}).touchend(function(b){c.handleMouse(b,a,"clickItem")}).mouseover(function(b){c.handleMouse(b,a,"rollOverItem")}).mouseout(function(b){c.handleMouse(b,a,"rollOutItem")})},handleMouse:function(a,b,c){this.fire({type:c,value:b.value,serialDataItem:b.serialDataItem,axis:this,target:b.label,chart:this.chart,event:a})},addGuide:function(a){for(var b=this.guides,c=!1,e=b.length,h=0;h<b.length;h++)b[h]==a&&(c=!0,e=h);a=d.processObject(a,d.Guide,this.theme);a.id||(a.id="guideAuto"+e+"_"+(new Date).getTime());c||b.push(a)},removeGuide:function(a){var b=this.guides,c;for(c=0;c<b.length;c++)b[c]==a&&b.splice(c,1)},handleGuideOver:function(a){clearTimeout(this.chart.hoverInt);var b=a.graphics.getBBox(),c=this.x+b.x+b.width/2,b=this.y+b.y+b.height/2,e=a.fillColor;void 0===e&&(e=a.lineColor);this.chart.showBalloon(a.balloonText,e,!0,c,b);this.fire({type:"rollOverGuide",guide:a,chart:this.chart})},handleGuideOut:function(a){this.chart.hideBalloon();this.fire({type:"rollOutGuide",guide:a,chart:this.chart})},handleGuideClick:function(a){this.chart.hideBalloon();this.fire({type:"clickGuide",guide:a,chart:this.chart})},addEventListeners:function(a,b){var c=this;a.mouseover(function(){c.handleGuideOver(b)});a.mouseup(function(){c.handleGuideClick(b)});a.touchstart(function(){c.handleGuideOver(b)});a.mouseout(function(){c.handleGuideOut(b)})},getBBox:function(){var a;this.labelsSet&&(a=this.labelsSet.getBBox());a?d.VML||(a={x:a.x+this.x,y:a.y+this.y,width:a.width,height:a.height}):a={x:0,y:0,width:0,height:0};return a},destroy:function(){d.remove(this.set);d.remove(this.labelsSet);var a=this.axisLine;a&&d.remove(a.axisSet);d.remove(this.grid0)},chooseMinorFrequency:function(a){for(var b=10;0<b;b--)if(a/ -b==Math.round(a/b))return a/b},parseDatesDraw:function(){var a,b=this.chart,c=this.showFirstLabel,e=this.showLastLabel,h,f="",g=d.extractPeriod(this.minPeriod),k=d.getPeriodDuration(g.period,g.count),l,m,p,q,n,t=this.firstDayOfWeek,r=this.boldPeriodBeginning;a=this.minorGridEnabled;var w,z=this.gridAlpha,x,u=this.choosePeriod(0),A=u.period,u=u.count,y=d.getPeriodDuration(A,u);y<k&&(A=g.period,u=g.count,y=k);g=A;"WW"==g&&(g="DD");this.stepWidth=this.getStepWidth(this.timeDifference);var B=Math.ceil(this.timeDifference/ -y)+5,D=l=d.resetDateToMin(new Date(this.startTime-y),A,u,t).getTime();if(g==A&&1==u&&this.centerLabelOnFullPeriod||this.autoWrap||this.centerLabels)p=y*this.stepWidth,this.autoWrap&&!this.centerLabels&&(p=-p);this.cellWidth=k*this.stepWidth;q=Math.round(l/y);k=-1;q/2==Math.round(q/2)&&(k=-2,l-=y);q=this.firstTime;var C=0,I=0;a&&1<u&&(w=this.chooseMinorFrequency(u),x=d.getPeriodDuration(A,w),"DD"==A&&(x+=d.getPeriodDuration("hh")),"fff"==A&&(x=1));if(0<this.gridCountR)for(B-5-k>this.autoRotateCount&&!isNaN(this.autoRotateAngle)&&(this.labelRotationR=this.autoRotateAngle),a=k;a<=B;a++){n=q+y*(a+Math.floor((D-q)/y))-C;"DD"==A&&(n+=36E5);n=d.resetDateToMin(new Date(n),A,u,t).getTime();"MM"==A&&(h=(n-l)/y,1.5<=(n-l)/y&&(n=n-(h-1)*y+d.getPeriodDuration("DD",3),n=d.resetDateToMin(new Date(n),A,1).getTime(),C+=y));h=(n-this.startTime)*this.stepWidth;if("radar"==b.type){if(h=this.axisWidth-h,0>h||h>this.axisWidth)continue}else this.rotate?"date"==this.type&&"middle"==this.gridPosition&&(I=-y*this.stepWidth/ -2):"date"==this.type&&(h=this.axisWidth-h);f=!1;this.nextPeriod[g]&&(f=this.checkPeriodChange(this.nextPeriod[g],1,n,l,g));l=!1;f&&this.markPeriodChange?(f=this.dateFormatsObject[this.nextPeriod[g]],this.twoLineMode&&(f=this.dateFormatsObject[g]+"\n"+f,f=d.fixBrakes(f)),l=!0):f=this.dateFormatsObject[g];r||(l=!1);this.currentDateFormat=f;f=d.formatDate(new Date(n),f,b);if(a==k&&!c||a==B&&!e)f=" ";this.labelFunction&&(f=this.labelFunction(f,new Date(n),this,A,u,m).toString());this.boldLabels&&(l=!0);m=new this.axisItemRenderer(this,h,f,!1,p,I,!1,l);this.pushAxisItem(m);m=l=n;if(!isNaN(w))for(h=1;h<u;h+=w)this.gridAlpha=this.minorGridAlpha,f=n+x*h,f=d.resetDateToMin(new Date(f),A,w,t).getTime(),f=new this.axisItemRenderer(this,(f-this.startTime)*this.stepWidth,void 0,void 0,void 0,void 0,void 0,void 0,void 0,!0),this.pushAxisItem(f);this.gridAlpha=z}},choosePeriod:function(a){var b=d.getPeriodDuration(this.periods[a].period,this.periods[a].count),c=this.periods;return this.timeDifference<b&&0<a?c[a-1]:Math.ceil(this.timeDifference/b)<=this.gridCountR?c[a]:a+1<c.length?this.choosePeriod(a+1):c[a]},getStepWidth:function(a){var b;this.startOnAxis?(b=this.axisWidth/(a-1),1==a&&(b=this.axisWidth)):b=this.axisWidth/a;return b},timeZoom:function(a,b){this.startTime=a;this.endTime=b},minDuration:function(){var a=d.extractPeriod(this.minPeriod);return d.getPeriodDuration(a.period,a.count)},checkPeriodChange:function(a,b,c,e,h){c=new Date(c);var f=new Date(e),g=this.firstDayOfWeek;e=b;"DD"==a&&(b=1);c=d.resetDateToMin(c,a,b,g).getTime();b=d.resetDateToMin(f,a,b,g).getTime();return"DD"==a&&"hh"!=h&&c-b<d.getPeriodDuration(a,e)-d.getPeriodDuration("hh",1)?!1:c!=b?!0:!1},generateDFObject:function(){this.dateFormatsObject={};var a;for(a=0;a<this.dateFormats.length;a++){var b=this.dateFormats[a];this.dateFormatsObject[b.period]=b.format}},hideBalloon:function(){this.balloon&&this.balloon.hide&&this.balloon.hide();this.prevBY=this.prevBX=NaN},formatBalloonText:function(a){return a},showBalloon:function(a,b,c,e){var d=this.offset;switch(this.position){case"bottom":b=this.height+d;break;case"top":b=-d;break;case"left":a=-d;break;case"right":a=this.width+d}c||(c=this.currentDateFormat);if("V"==this.orientation){if(0>b||b>this.height)return;if(isNaN(b)){this.hideBalloon();return}b=this.adjustBalloonCoordinate(b,e);e=this.coordinateToValue(b)}else{if(0>a||a>this.width)return;if(isNaN(a)){this.hideBalloon();return}a=this.adjustBalloonCoordinate(a,e);e=this.coordinateToValue(a)}var f;if(d=this.chart.chartCursor)f=d.index;if(this.balloon&&void 0!==e&&this.balloon.enabled){if(this.balloonTextFunction){if("date"==this.type||!0===this.parseDates)e=new Date(e);e=this.balloonTextFunction(e)}else this.balloonText?e=this.formatBalloonText(this.balloonText,f,c):isNaN(e)||(e=this.formatValue(e,c));if(a!=this.prevBX||b!=this.prevBY)this.balloon.setPosition(a,b),this.prevBX=a,this.prevBY=b,e&&this.balloon.showBalloon(e)}},adjustBalloonCoordinate:function(a){return a},createBalloon:function(){var a=this.chart,b=a.chartCursor;b&&(b=b.cursorPosition,"mouse"!=b&&(this.stickBalloonToCategory=!0),"start"==b&&(this.stickBalloonToStart=!0),"ValueAxis"==this.cname&&(this.stickBalloonToCategory=!1));this.balloon&&(this.balloon.destroy&&this.balloon.destroy(),d.extend(this.balloon,a.balloon,!0))},setBalloonBounds:function(){var a=this.balloon;if(a){var b=this.chart;a.cornerRadius=0;a.shadowAlpha=0;a.borderThickness=1;a.borderAlpha=1;a.adjustBorderColor=!1;a.showBullet=!1;this.balloon=a;a.chart=b;a.mainSet=b.plotBalloonsSet;a.pointerWidth=this.tickLength;if(this.parseDates||"date"==this.type)a.pointerWidth=0;a.className=this.id;b="V";"V"==this.orientation&&(b="H");this.stickBalloonToCategory||(a.animationDuration=0);var c,e,d,f,g=this.inside,k=this.width,l=this.height;switch(this.position){case"bottom":c=0;e=k;g?(d=0,f=l):(d=l,f=l+1E3);break;case"top":c=0;e=k;g?(d=0,f=l):(d=-1E3,f=0);break;case"left":d=0;f=l;g?(c=0,e=k):(c=-1E3,e=0);break;case"right":d=0,f=l,g?(c=0,e=k):(c=k,e=k+1E3)}a.drop||(a.pointerOrientation=b);a.setBounds(c,d,e,f)}}})})();(function(){var d=window.AmCharts;d.ValueAxis=d.Class({inherits:d.AxisBase,construct:function(a){this.cname="ValueAxis";this.createEvents("axisChanged","logarithmicAxisFailed","axisZoomed","axisIntZoomed");d.ValueAxis.base.construct.call(this,a);this.dataChanged=!0;this.stackType="none";this.position="left";this.unitPosition="right";this.includeAllValues=this.recalculateToPercents=this.includeHidden=this.includeGuidesInMinMax=this.integersOnly=!1;this.durationUnits={DD:"d. ",hh:":",mm:":",ss:""};this.scrollbar=!1;this.baseValue=0;this.radarCategoriesEnabled=!0;this.axisFrequency=1;this.gridType="polygons";this.useScientificNotation=!1;this.axisTitleOffset=10;this.pointPosition="axis";this.minMaxMultiplier=1;this.logGridLimit=2;this.totalTextOffset=this.treatZeroAs=0;this.minPeriod="ss";this.relativeStart=0;this.relativeEnd=1;d.applyTheme(this,a,this.cname)},updateData:function(){0>=this.gridCountR&&(this.gridCountR=1);this.totals=[];this.data=this.chart.chartData;var a=this.chart;"xy"!=a.type&&(this.stackGraphs("smoothedLine"),this.stackGraphs("line"),this.stackGraphs("column"),this.stackGraphs("step"));this.recalculateToPercents&&this.recalculate();this.synchronizationMultiplier&&this.synchronizeWith?(d.isString(this.synchronizeWith)&&(this.synchronizeWith=a.getValueAxisById(this.synchronizeWith)),this.synchronizeWith&&(this.synchronizeWithAxis(this.synchronizeWith),this.foundGraphs=!0)):(this.foundGraphs=!1,this.getMinMax(),0===this.start&&this.end==this.data.length-1&&isNaN(this.minZoom)&&isNaN(this.maxZoom)&&(this.fullMin=this.min,this.fullMax=this.max,"date"!=this.type&&this.strictMinMax&&(isNaN(this.minimum)||(this.fullMin=this.minimum),isNaN(this.maximum)||(this.fullMax=this.maximum)),this.logarithmic&&(this.fullMin=this.logMin,0===this.fullMin&&(this.fullMin=this.treatZeroAs)),"date"==this.type&&(this.minimumDate||(this.fullMin=this.minRR),this.maximumDate||(this.fullMax=this.maxRR),this.strictMinMax&&(this.minimumDate&&(this.fullMin=this.minimumDate.getTime()),this.maximumDate&&(this.fullMax=this.maximumDate.getTime())))))},draw:function(){d.ValueAxis.base.draw.call(this);var a=this.chart,b=this.set;this.labelRotationR=this.labelRotation;d.setCN(a,this.set,"value-axis value-axis-"+this.id);d.setCN(a,this.labelsSet,"value-axis value-axis-"+this.id);d.setCN(a,this.axisLine.axisSet,"value-axis value-axis-"+this.id);var c=this.type;"duration"==c&&(this.duration="ss");!0===this.dataChanged&&(this.updateData(),this.dataChanged=!1);"date"==c&&(this.logarithmic=!1,this.min=this.minRR,this.max=this.maxRR,this.reversed=!1,this.getDateMinMax());if(this.logarithmic){var e=this.treatZeroAs,h=this.getExtremes(0,this.data.length-1).min;!isNaN(this.minimum)&&this.minimum<h&&(h=this.minimum);this.logMin=h;this.minReal<h&&(this.minReal=h);isNaN(this.minReal)&&(this.minReal=h);0<e&&0===h&&(this.minReal=h=e);if(0>=h||0>=this.minimum){this.fire({type:"logarithmicAxisFailed",chart:a});return}}this.grid0=null;var f,g,k=a.dx,l=a.dy,e=!1,h=this.logarithmic;if(isNaN(this.min)||isNaN(this.max)||!this.foundGraphs||Infinity==this.min||-Infinity==this.max)e=!0;else{"date"==this.type&&this.min==this.max&&(this.max+=this.minDuration(),this.min-=this.minDuration());var m=this.labelFrequency,p=this.showFirstLabel,q=this.showLastLabel,n=1,t=0;this.minCalc=this.min;this.maxCalc=this.max;if(this.strictMinMax&&(isNaN(this.minimum)||(this.min=this.minimum),isNaN(this.maximum)||(this.max=this.maximum),this.min==this.max))return;isNaN(this.minZoom)||(this.minReal=this.min=this.minZoom);isNaN(this.maxZoom)||(this.max=this.maxZoom);if(this.logarithmic){g=this.fullMin;var r=this.fullMax;isNaN(this.minimum)||(g=this.minimum);isNaN(this.maximum)||(r=this.maximum);var r=Math.log(r)*Math.LOG10E-Math.log(g)*Math.LOG10E,w=Math.log(this.max)/Math.LN10-Math.log(g)*Math.LOG10E;this.relativeStart=d.roundTo((Math.log(this.minReal)/Math.LN10-Math.log(g)*Math.LOG10E)/r,5);this.relativeEnd=d.roundTo(w/r,5)}else this.relativeStart=d.roundTo(d.fitToBounds((this.min-this.fullMin)/(this.fullMax-this.fullMin),0,1),5),this.relativeEnd= -d.roundTo(d.fitToBounds((this.max-this.fullMin)/(this.fullMax-this.fullMin),0,1),5);var r=Math.round((this.maxCalc-this.minCalc)/this.step)+1,z;!0===h?(z=Math.log(this.max)*Math.LOG10E-Math.log(this.minReal)*Math.LOG10E,this.stepWidth=this.axisWidth/z,z>this.logGridLimit&&(r=Math.ceil(Math.log(this.max)*Math.LOG10E)+1,t=Math.round(Math.log(this.minReal)*Math.LOG10E),r>this.gridCountR&&(n=Math.ceil(r/this.gridCountR)))):this.stepWidth=this.axisWidth/(this.max-this.min);var x=0;1>this.step&&-1<this.step&& -(x=d.getDecimals(this.step));this.integersOnly&&(x=0);x>this.maxDecCount&&(x=this.maxDecCount);w=this.precision;isNaN(w)||(x=w);isNaN(this.maxZoom)&&(this.max=d.roundTo(this.max,this.maxDecCount),this.min=d.roundTo(this.min,this.maxDecCount));g={};g.precision=x;g.decimalSeparator=a.nf.decimalSeparator;g.thousandsSeparator=a.nf.thousandsSeparator;this.numberFormatter=g;var u;this.exponential=!1;for(g=t;g<r;g+=n){var A=d.roundTo(this.step*g+this.min,x);-1!=String(A).indexOf("e")&&(this.exponential=!0)}this.duration&&(this.maxInterval=d.getMaxInterval(this.max,this.duration));var x=this.step,y,A=this.minorGridAlpha;this.minorGridEnabled&&(y=this.getMinorGridStep(x,this.stepWidth*x));if(this.autoGridCount||0!==this.gridCount)if("date"==c)this.generateDFObject(),this.timeDifference=this.max-this.min,this.maxTime=this.lastTime=this.max,this.startTime=this.firstTime=this.min,this.parseDatesDraw();else for(r>=this.autoRotateCount&&!isNaN(this.autoRotateAngle)&&(this.labelRotationR=this.autoRotateAngle),c=this.minCalc,h&&(r++,c=this.maxCalc-r*x),this.gridCountReal=r,g=this.startCount=t;g<r;g+=n)if(t=x*g+c,t=d.roundTo(t,this.maxDecCount+1),!this.integersOnly||Math.round(t)==t)if(isNaN(w)||Number(d.toFixed(t,w))==t){if(!0===h)if(z>this.logGridLimit)t=Math.pow(10,g);else if(0>=t&&(t=c+x*g+x/2,0>=t))continue;u=this.formatValue(t,!1,g);Math.round(g/m)!=g/m&&(u=void 0);if(0===g&&!p||g==r-1&&!q)u=" ";f=this.getCoordinate(t);var B;this.rotate&&this.autoWrap&&(B=this.stepWidth*x-10);u=new this.axisItemRenderer(this,f,u,void 0,B,void 0,void 0,this.boldLabels);this.pushAxisItem(u);if(t==this.baseValue&&"radar"!=a.type){var D,C,I=this.width,H=this.height;"H"==this.orientation?0<=f&&f<=I+1&&(D=[f,f,f+k],C=[H,0,l]):0<=f&&f<=H+1&&(D=[0,I,I+k],C=[f,f,f+l]);D&&(f=d.fitToBounds(2*this.gridAlpha,0,1),isNaN(this.zeroGridAlpha)||(f=this.zeroGridAlpha),f=d.line(a.container,D,C,this.gridColor,f,1,this.dashLength),f.translate(this.x,this.y),this.grid0=f,a.axesSet.push(f),f.toBack(),d.setCN(a,f,this.bcn+"zero-grid-"+this.id),d.setCN(a,f,this.bcn+"zero-grid"))}if(!isNaN(y)&&0<A&&g<r-1){f=x/y;h&&(y=x*(g+n)+this.minCalc,y=d.roundTo(y,this.maxDecCount+1),z>this.logGridLimit&&(y=Math.pow(10,g+n)),f=9,y=(y-t)/f);I=this.gridAlpha;this.gridAlpha=this.minorGridAlpha;for(H=1;H<f;H++){var Q=this.getCoordinate(t+y*H),Q=new this.axisItemRenderer(this,Q,"",!1,0,0,!1,!1,0,!0);this.pushAxisItem(Q)}this.gridAlpha=I}}z=this.guides;B=z.length;if(0<B){D=this.fillAlpha;for(g=this.fillAlpha=0;g<B;g++)C=z[g],k=NaN,y=C.above,isNaN(C.toValue)|| -(k=this.getCoordinate(C.toValue),u=new this.axisItemRenderer(this,k,"",!0,NaN,NaN,C),this.pushAxisItem(u,y)),l=NaN,isNaN(C.value)||(l=this.getCoordinate(C.value),u=new this.axisItemRenderer(this,l,C.label,!0,NaN,(k-l)/2,C),this.pushAxisItem(u,y)),isNaN(k)&&(l-=3,k=l+3),u&&(m=u.label)&&this.addEventListeners(m,C),isNaN(k-l)||0>l&&0>k||(k=new this.guideFillRenderer(this,l,k,C),this.pushAxisItem(k,y),y=k.graphics(),C.graphics=y,this.addEventListeners(y,C));this.fillAlpha=D}u=this.baseValue;this.min> -this.baseValue&&this.max>this.baseValue&&(u=this.min);this.min<this.baseValue&&this.max<this.baseValue&&(u=this.max);h&&u<this.minReal&&(u=this.minReal);this.baseCoord=this.getCoordinate(u,!0);u={type:"axisChanged",target:this,chart:a};u.min=h?this.minReal:this.min;u.max=this.max;this.fire(u);this.axisCreated=!0}h=this.axisLine.set;u=this.labelsSet;b.translate(this.x,this.y);u.translate(this.x,this.y);this.positionTitle();"radar"!=a.type&&h.toFront();!this.visible||e?(b.hide(),h.hide(),u.hide()):(b.show(),h.show(),u.show());this.axisY=this.y;this.axisX=this.x},getDateMinMax:function(){this.minimumDate&&(this.minimumDate instanceof Date||(this.minimumDate=d.getDate(this.minimumDate,this.chart.dataDateFormat,"fff")),this.min=this.minimumDate.getTime());this.maximumDate&&(this.maximumDate instanceof Date||(this.maximumDate=d.getDate(this.maximumDate,this.chart.dataDateFormat,"fff")),this.max=this.maximumDate.getTime())},formatValue:function(a,b,c){var e=this.exponential,h=this.logarithmic,f=this.numberFormatter,g=this.chart;if(f)return!0===this.logarithmic&&(e=-1!=String(a).indexOf("e")?!0:!1),this.useScientificNotation&&(e=!0),this.usePrefixes&&(e=!1),e?(c=-1==String(a).indexOf("e")?a.toExponential(15):String(a),e=c.split("e"),c=Number(e[0]),e=Number(e[1]),c=d.roundTo(c,14),b||isNaN(this.precision)||(c=d.roundTo(c,this.precision)),10==c&&(c=1,e+=1),c=c+"e"+e,0===a&&(c="0"),1==a&&(c="1")):(h&&(e=String(a).split("."),e[1]?(f.precision=e[1].length,0>c&&(f.precision=Math.abs(c)),b&&1<a&&(f.precision=0),b||isNaN(this.precision)||(f.precision=this.precision)):f.precision=-1),c=this.usePrefixes?d.addPrefix(a,g.prefixesOfBigNumbers,g.prefixesOfSmallNumbers,f,!b):d.formatNumber(a,f,f.precision)),this.duration&&(b&&(f.precision=0),c=d.formatDuration(a,this.duration,"",this.durationUnits,this.maxInterval,f)),"date"==this.type&&(c=d.formatDate(new Date(a),this.currentDateFormat,g)),this.recalculateToPercents?c+="%":(b=this.unit)&&(c="left"==this.unitPosition?b+c:c+b),this.labelFunction&&(c="date"==this.type?this.labelFunction(c,new Date(a),this).toString():this.labelFunction(a,c,this).toString()),c},getMinorGridStep:function(a,b){var c=[5,4,2];60>b&&c.shift();for(var e=Math.floor(Math.log(Math.abs(a))*Math.LOG10E),d=0;d<c.length;d++){var f=a/c[d],g=Math.floor(Math.log(Math.abs(f))*Math.LOG10E);if(!(1<Math.abs(e-g)))if(1>a){if(g=Math.pow(10,-g)*f,g==Math.round(g))return f}else if(f==Math.round(f))return f}},stackGraphs:function(a){var b=this.stackType;"stacked"==b&&(b="regular");"line"==b&&(b="none");"100% stacked"==b&&(b="100%");this.stackType=b;var c=[],e=[],h=[],f=[],g,k=this.chart.graphs,l,m,p,q,n,t=this.baseValue,r=!1;if("line"==a||"step"==a||"smoothedLine"==a)r=!0;if(r&&("regular"==b||"100%"==b))for(q=0;q<k.length;q++)p=k[q],p.stackGraph=null,p.hidden||(m=p.type,p.chart==this.chart&&p.valueAxis==this&&a==m&&p.stackable&&(l&&(p.stackGraph=l),l=p));p=this.start-10;l=this.end+10;q=this.data.length-1;p=d.fitToBounds(p,0,q);l=d.fitToBounds(l,0,q);for(n=p;n<=l;n++){var w=0;for(q=0;q<k.length;q++)if(p=k[q],p.hidden)p.newStack&&(h[n]=NaN,e[n]=NaN);else if(m=p.type,p.chart==this.chart&&p.valueAxis==this&&a==m&&p.stackable)if(m=this.data[n].axes[this.id].graphs[p.id],g=m.values.value,isNaN(g))p.newStack&&(h[n]=NaN,e[n]=NaN);else{var z=d.getDecimals(g);w<z&&(w=z);isNaN(f[n])?f[n]=Math.abs(g):f[n]+=Math.abs(g);f[n]=d.roundTo(f[n],w);z=p.fillToGraph;r&&z&&(z=this.data[n].axes[this.id].graphs[z.id])&&(m.values.open=z.values.value);"regular"==b&&(r&&(isNaN(c[n])?(c[n]=g,m.values.close=g,m.values.open=this.baseValue):(isNaN(g)?m.values.close=c[n]:m.values.close=g+c[n],m.values.open=c[n],c[n]=m.values.close)),"column"==a&&(p.newStack&&(h[n]=NaN,e[n]=NaN),m.values.close=g,0>g?(m.values.close=g,isNaN(e[n])?m.values.open=t:(m.values.close+=e[n],m.values.open=e[n]),e[n]=m.values.close):(m.values.close=g,isNaN(h[n])?m.values.open=t:(m.values.close+=h[n],m.values.open=h[n]),h[n]=m.values.close)))}}for(n=this.start;n<=this.end;n++)for(q=0;q<k.length;q++)(p=k[q],p.hidden)?p.newStack&&(h[n]=NaN,e[n]=NaN):(m=p.type,p.chart==this.chart&&p.valueAxis==this&&a==m&&p.stackable&&(m=this.data[n].axes[this.id].graphs[p.id],g=m.values.value,isNaN(g)||(c=g/f[n]*100,m.values.percents=c,m.values.total=f[n],p.newStack&&(h[n]=NaN,e[n]=NaN),"100%"==b&&(isNaN(e[n])&&(e[n]=0),isNaN(h[n])&&(h[n]=0),0>c?(m.values.close=d.fitToBounds(c+e[n],-100,100),m.values.open=e[n],e[n]=m.values.close):(m.values.close=d.fitToBounds(c+h[n],-100,100),m.values.open=h[n],h[n]=m.values.close)))))},recalculate:function(){var a=this.chart,b=a.graphs,c;for(c=0;c<b.length;c++){var e=b[c];if(e.valueAxis==this){var h="value";if("candlestick"==e.type||"ohlc"==e.type)h="open";var f,g,k=this.end+2,k=d.fitToBounds(this.end+1,0,this.data.length-1),l=this.start;0<l&&l--;var m;g=this.start;e.compareFromStart&&(g=0);if(!isNaN(a.startTime)&&(m=a.categoryAxis)){var p=m.minDuration(),p=new Date(a.startTime+p/2),q=d.resetDateToMin(new Date(a.startTime),m.minPeriod).getTime();d.resetDateToMin(new Date(p),m.minPeriod).getTime()>q&&g++}if(m=a.recalculateFromDate)m=d.getDate(m,a.dataDateFormat,"fff"),g=a.getClosestIndex(a.chartData,"time",m.getTime(),!0,0,a.chartData.length),k=a.chartData.length-1;for(m=g;m<=k&&(g=this.data[m].axes[this.id].graphs[e.id],f=g.values[h],e.recalculateValue&&(f=g.dataContext[e.valueField+e.recalculateValue]),isNaN(f));m++);this.recBaseValue=f;for(h=l;h<=k;h++){g=this.data[h].axes[this.id].graphs[e.id];g.percents={};var l=g.values,n;for(n in l)g.percents[n]="percents"!=n?l[n]/f*100-100:l[n]}}}},getMinMax:function(){var a=!1,b=this.chart,c=b.graphs,e;for(e=0;e<c.length;e++){var h=c[e].type;("line"==h||"step"==h||"smoothedLine"==h)&&this.expandMinMax&&(a=!0)}a&&(0<this.start&&this.start--,this.end<this.data.length-1&&this.end++);"serial"==b.type&&(!0!==b.categoryAxis.parseDates||a||this.end<this.data.length-1&&this.end++);this.includeAllValues&&(this.start=0,this.end=this.data.length-1);a=this.minMaxMultiplier;b=this.getExtremes(this.start,this.end);this.min=b.min;this.max=b.max;this.minRR=this.min;this.maxRR=this.max;a=(this.max-this.min)*(a-1);this.min-=a;this.max+=a;a=this.guides.length;if(this.includeGuidesInMinMax&&0<a)for(b=0;b<a;b++)c=this.guides[b],c.toValue<this.min&&(this.min=c.toValue),c.value<this.min&&(this.min=c.value),c.toValue>this.max&&(this.max=c.toValue),c.value>this.max&&(this.max=c.value);isNaN(this.minimum)||(this.min=this.minimum);isNaN(this.maximum)||(this.max=this.maximum);"date"==this.type&&this.getDateMinMax();this.min>this.max&&(a=this.max,this.max=this.min,this.min=a);isNaN(this.minZoom)||(this.min=this.minZoom);isNaN(this.maxZoom)||(this.max=this.maxZoom);this.minCalc=this.min;this.maxCalc=this.max;this.minReal=this.min;this.maxReal=this.max;0===this.min&&0===this.max&&(this.max=9);this.min>this.max&&(this.min=this.max-1);a=this.min;b=this.max;c=this.max-this.min;e=0===c?Math.pow(10,Math.floor(Math.log(Math.abs(this.max))*Math.LOG10E))/10:Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;isNaN(this.maximum)&&(this.max=Math.ceil(this.max/e)*e+e);isNaN(this.minimum)&&(this.min= -Math.floor(this.min/e)*e-e);0>this.min&&0<=a&&(this.min=0);0<this.max&&0>=b&&(this.max=0);"100%"==this.stackType&&(this.min=0>this.min?-100:0,this.max=0>this.max?0:100);c=this.max-this.min;e=Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;this.step=Math.ceil(c/this.gridCountR/e)*e;c=Math.pow(10,Math.floor(Math.log(Math.abs(this.step))*Math.LOG10E));c=d.fixStepE(c);e=Math.ceil(this.step/c);5<e&&(e=10);5>=e&&2<e&&(e=5);this.step=Math.ceil(this.step/(c*e))*c*e;isNaN(this.setStep)||(this.step= -this.setStep);1>c?(this.maxDecCount=Math.abs(Math.log(Math.abs(c))*Math.LOG10E),this.maxDecCount=Math.round(this.maxDecCount),this.step=d.roundTo(this.step,this.maxDecCount+1)):this.maxDecCount=0;this.min=this.step*Math.floor(this.min/this.step);this.max=this.step*Math.ceil(this.max/this.step);0>this.min&&0<=a&&(this.min=0);0<this.max&&0>=b&&(this.max=0);1<this.minReal&&1<this.max-this.minReal&&(this.minReal=Math.floor(this.minReal));c=Math.pow(10,Math.floor(Math.log(Math.abs(this.minReal))*Math.LOG10E));0===this.min&&(this.minReal=c);0===this.min&&1<this.minReal&&(this.minReal=1);0<this.min&&0<this.minReal-this.step&&(this.minReal=this.min+this.step<this.minReal?this.min+this.step:this.min);this.logarithmic&&(2<Math.log(b)*Math.LOG10E-Math.log(a)*Math.LOG10E?(this.minReal=this.min=Math.pow(10,Math.floor(Math.log(Math.abs(a))*Math.LOG10E)),this.maxReal=this.max=Math.pow(10,Math.ceil(Math.log(Math.abs(b))*Math.LOG10E))):(a=Math.pow(10,Math.floor(Math.log(Math.abs(a))*Math.LOG10E))/10,Math.pow(10,Math.floor(Math.log(Math.abs(this.min))* -Math.LOG10E))/10<a&&(this.minReal=this.min=10*a)))},getExtremes:function(a,b){var c,e,d;for(d=a;d<=b;d++){var f=this.data[d].axes[this.id].graphs,g;for(g in f)if(f.hasOwnProperty(g)){var k=this.chart.graphsById[g];if(k.includeInMinMax&&(!k.hidden||this.includeHidden)){isNaN(c)&&(c=Infinity);isNaN(e)&&(e=-Infinity);this.foundGraphs=!0;k=f[g].values;this.recalculateToPercents&&(k=f[g].percents);var l;if(this.minMaxField)l=k[this.minMaxField],l<c&&(c=l),l>e&&(e=l);else for(var m in k)k.hasOwnProperty(m)&& -"percents"!=m&&"total"!=m&&"error"!=m&&(l=k[m],l<c&&(c=l),l>e&&(e=l))}}}return{min:c,max:e}},zoomOut:function(a){this.maxZoom=this.minZoom=NaN;this.zoomToRelativeValues(0,1,a)},zoomToRelativeValues:function(a,b,c){if(this.reversed){var e=a;a=1-b;b=1-e}var d=this.fullMax,e=this.fullMin,f=e+(d-e)*a,g=e+(d-e)*b;0<=this.minimum&&0>f&&(f=0);this.logarithmic&&(isNaN(this.minimum)||(e=this.minimum),isNaN(this.maximum)||(d=this.maximum),d=Math.log(d)*Math.LOG10E-Math.log(e)*Math.LOG10E,f=Math.pow(10,d*a+ -Math.log(e)*Math.LOG10E),g=Math.pow(10,d*b+Math.log(e)*Math.LOG10E));return this.zoomToValues(f,g,c)},zoomToValues:function(a,b,c){if(b<a){var e=b;b=a;a=e}var h=this.fullMax,e=this.fullMin;this.relativeStart=d.roundTo((a-e)/(h-e),9);this.relativeEnd=d.roundTo((b-e)/(h-e),9);if(this.logarithmic){isNaN(this.minimum)||(e=this.minimum);isNaN(this.maximum)||(h=this.maximum);var h=Math.log(h)*Math.LOG10E-Math.log(e)*Math.LOG10E,f=Math.log(b)/Math.LN10-Math.log(e)*Math.LOG10E;this.relativeStart=d.roundTo((Math.log(a)/ -Math.LN10-Math.log(e)*Math.LOG10E)/h,9);this.relativeEnd=d.roundTo(f/h,9)}if(this.minZoom!=a||this.maxZoom!=b)return this.minZoom=a,this.maxZoom=b,e={type:"axisZoomed"},e.chart=this.chart,e.valueAxis=this,e.startValue=a,e.endValue=b,e.relativeStart=this.relativeStart,e.relativeEnd=this.relativeEnd,this.prevStartValue==a&&this.prevEndValue==b||this.fire(e),this.prevStartValue=a,this.prevEndValue=b,c||(a={},d.copyProperties(e,a),a.type="axisIntZoomed",this.fire(a)),0===this.relativeStart&&1==this.relativeEnd&& -(this.maxZoom=this.minZoom=NaN),!0},coordinateToValue:function(a){if(isNaN(a))return NaN;var b=this.axisWidth,c=this.stepWidth,e=this.reversed,d=this.rotate,f=this.min,g=this.minReal;return!0===this.logarithmic?Math.pow(10,(d?!0===e?(b-a)/c:a/c:!0===e?a/c:(b-a)/c)+Math.log(g)*Math.LOG10E):!0===e?d?f-(a-b)/c:a/c+f:d?a/c+f:f-(a-b)/c},getCoordinate:function(a,b){if(isNaN(a))return NaN;var c=this.rotate,e=this.reversed,d=this.axisWidth,f=this.stepWidth,g=this.min,k=this.minReal;!0===this.logarithmic? -(0===a&&(a=this.treatZeroAs),g=Math.log(a)*Math.LOG10E-Math.log(k)*Math.LOG10E,c=c?!0===e?d-f*g:f*g:!0===e?f*g:d-f*g):c=!0===e?c?d-f*(a-g):f*(a-g):c?f*(a-g):d-f*(a-g);1E7<Math.abs(c)&&(c=c/Math.abs(c)*1E7);b||(c=Math.round(c));return c},synchronizeWithAxis:function(a){this.synchronizeWith=a;this.listenTo(this.synchronizeWith,"axisChanged",this.handleSynchronization)},handleSynchronization:function(){if(this.synchronizeWith){d.isString(this.synchronizeWith)&&(this.synchronizeWith=this.chart.getValueAxisById(this.synchronizeWith));var a=this.synchronizeWith,b=a.min,c=a.max,a=a.step,e=this.synchronizationMultiplier;e&&(this.min=b*e,this.max=c*e,this.step=a*e,b=Math.abs(Math.log(Math.abs(Math.pow(10,Math.floor(Math.log(Math.abs(this.step))*Math.LOG10E))))*Math.LOG10E),this.maxDecCount=b=Math.round(b),this.draw())}}})})();(function(){var d=window.AmCharts;d.RecAxis=d.Class({construct:function(a){var b=a.chart,c=a.axisThickness,e=a.axisColor,h=a.axisAlpha,f=a.offset,g=a.dx,k=a.dy,l=a.x,m=a.y,p=a.height,q=a.width,n=b.container;"H"==a.orientation?(e=d.line(n,[0,q],[0,0],e,h,c),this.axisWidth=a.width,"bottom"==a.position?(k=c/2+f+p+m-1,c=l):(k=-c/2-f+m+k,c=g+l)):(this.axisWidth=a.height,"right"==a.position?(e=d.line(n,[0,0,-g],[0,p,p-k],e,h,c),k=m+k,c=c/2+f+g+q+l-1):(e=d.line(n,[0,0],[0,p],e,h,c),k=m,c=-c/2-f+l));e.translate(c,k);c=b.container.set();c.push(e);b.axesSet.push(c);d.setCN(b,e,a.bcn+"line");this.axisSet=c;this.set=e}})})();(function(){var d=window.AmCharts;d.RecItem=d.Class({construct:function(a,b,c,e,h,f,g,k,l,m,p,q){b=Math.round(b);var n=a.chart;this.value=c;void 0==c&&(c="");l||(l=0);void 0==e&&(e=!0);var t=n.fontFamily,r=a.fontSize;void 0==r&&(r=n.fontSize);var w=a.color;void 0==w&&(w=n.color);void 0!==p&&(w=p);var z=a.chart.container,x=z.set();this.set=x;var u=a.axisThickness,A=a.axisColor,y=a.axisAlpha,B=a.tickLength,D=a.gridAlpha,C=a.gridThickness,I=a.gridColor,H=a.dashLength,Q=a.fillColor,M=a.fillAlpha,P=a.labelsEnabled;p=a.labelRotationR;var ia=a.counter,J=a.inside,aa=a.labelOffset,ma=a.dx,na=a.dy,Pa=a.orientation,Z=a.position,da=a.previousCoord,X=a.height,xa=a.width,ea=a.offset,fa,Ba;g?(void 0!==g.id&&(q=n.classNamePrefix+"-guide-"+g.id),P=!0,isNaN(g.tickLength)||(B=g.tickLength),void 0!=g.lineColor&&(I=g.lineColor),void 0!=g.color&&(w=g.color),isNaN(g.lineAlpha)||(D=g.lineAlpha),isNaN(g.dashLength)||(H=g.dashLength),isNaN(g.lineThickness)||(C=g.lineThickness),!0===g.inside&&(J=!0,0<ea&&(ea=0)),isNaN(g.labelRotation)||(p=g.labelRotation),isNaN(g.fontSize)||(r=g.fontSize),g.position&&(Z=g.position),void 0!==g.boldLabel&&(k=g.boldLabel),isNaN(g.labelOffset)||(aa=g.labelOffset)):""===c&&(B=0);m&&!isNaN(a.minorTickLength)&&(B=a.minorTickLength);var ga="start";0<h&&(ga="middle");a.centerLabels&&(ga="middle");var V=p*Math.PI/180,Y,Da,G=0,v=0,oa=0,ha=Y=0,Qa=0;"V"==Pa&&(p=0);var ca;P&&""!==c&&(ca=a.autoWrap&&0===p?d.wrappedText(z,c,w,t,r,ga,k,Math.abs(h),0):d.text(z,c,w,t,r,ga,k),ga=ca.getBBox(),ha=ga.width,Qa=ga.height);if("H"==Pa){if(0<=b&&b<=xa+1&&(0<B&&0<y&&b+l<=xa+1&&(fa=d.line(z,[b+l,b+l],[0,B],A,y,C),x.push(fa)),0<D&&(Ba=d.line(z,[b,b+ma,b+ma],[X,X+na,na],I,D,C,H),x.push(Ba))),v=0,G=b,g&&90==p&&J&&(G-=r),!1===e?(ga="start",v="bottom"==Z?J?v+B:v-B:J?v-B:v+B,G+=3,0<h&&(G+=h/2-3,ga="middle"),0<p&&(ga="middle")):ga="middle",1==ia&&0<M&&!g&&!m&&da<xa&&(e=d.fitToBounds(b,0,xa),da=d.fitToBounds(da,0,xa),Y=e-da,0<Y&&(Da=d.rect(z,Y,a.height,Q,M),Da.translate(e-Y+ma,na),x.push(Da))),"bottom"==Z?(v+=X+r/2+ea,J?(0<p?(v=X-ha/2*Math.sin(V)-B-3,a.centerRotatedLabels||(G+=ha/2*Math.cos(V)-4+2)):0>p?(v=X+ha*Math.sin(V)-B-3+2,G+=-ha*Math.cos(V)-Qa*Math.sin(V)-4):v-=B+r+3+3,v-=aa):(0<p?(v=X+ha/2*Math.sin(V)+B+3,a.centerRotatedLabels||(G-=ha/2*Math.cos(V))):0>p?(v=X+B+3-ha/2*Math.sin(V)+2,G+=ha/2*Math.cos(V)):v+=B+u+3+3,v+=aa)):(v+=na+r/2-ea,G+=ma,J?(0<p?(v=ha/2*Math.sin(V)+B+3,a.centerRotatedLabels||(G-=ha/2*Math.cos(V))):v+=B+3,v+=aa):(0<p?(v=-(ha/2)*Math.sin(V)-B-6,a.centerRotatedLabels||(G+=ha/2*Math.cos(V))):v-=B+ -r+3+u+3,v-=aa)),"bottom"==Z?Y=(J?X-B-1:X+u-1)+ea:(oa=ma,Y=(J?na:na-B-u+1)-ea),f&&(G+=f),r=G,0<p&&(r+=ha/2*Math.cos(V)),ca&&(f=0,J&&(f=ha/2*Math.cos(V)),r+f>xa+2||0>r))ca.remove(),ca=null}else{0<=b&&b<=X+1&&(0<B&&0<y&&b+l<=X+1&&(fa=d.line(z,[0,B+1],[b+l,b+l],A,y,C),x.push(fa)),0<D&&(Ba=d.line(z,[0,ma,xa+ma],[b,b+na,b+na],I,D,C,H),x.push(Ba)));ga="end";if(!0===J&&"left"==Z||!1===J&&"right"==Z)ga="start";v=b-Qa/2+2;1==ia&&0<M&&!g&&!m&&(e=d.fitToBounds(b,0,X),da=d.fitToBounds(da,0,X),V=e-da,Da=d.polygon(z,[0,a.width,a.width,0],[0,0,V,V],Q,M),Da.translate(ma,e-V+na),x.push(Da));v+=r/2;"right"==Z?(G+=ma+xa+ea,v+=na,J?(f||(v-=r/2+3),G=G-(B+4)-aa):(G+=B+4+u,v-=2,G+=aa)):J?(G+=B+4-ea,f||(v-=r/2+3),g&&(G+=ma,v+=na),G+=aa):(G+=-B-u-4-2-ea,v-=2,G-=aa);fa&&("right"==Z?(oa+=ma+ea+xa-1,Y+=na,oa=J?oa-u:oa+u):(oa-=ea,J||(oa-=B+u)));f&&(v+=f);J=-3;"right"==Z&&(J+=na);ca&&(v>X+1||v<J-r/10)&&(ca.remove(),ca=null)}fa&&(fa.translate(oa,Y),d.setCN(n,fa,a.bcn+"tick"),d.setCN(n,fa,q,!0),g&&d.setCN(n,fa,"guide"));!1===a.visible&&(fa&&fa.remove(),ca&&(ca.remove(),ca=null));ca&&(ca.attr({"text-anchor":ga}),ca.translate(G,v,NaN,!0),0!==p&&ca.rotate(-p,a.chart.backgroundColor),a.allLabels.push(ca),this.label=ca,d.setCN(n,ca,a.bcn+"label"),d.setCN(n,ca,q,!0),g&&d.setCN(n,ca,"guide"));Ba&&(d.setCN(n,Ba,a.bcn+"grid"),d.setCN(n,Ba,q,!0),g&&d.setCN(n,Ba,"guide"));Da&&(d.setCN(n,Da,a.bcn+"fill"),d.setCN(n,Da,q,!0));m?Ba&&d.setCN(n,Ba,a.bcn+"grid-minor"):(a.counter=0===ia?1:0,a.previousCoord=b);0===this.set.node.childNodes.length&&this.set.remove()},graphics:function(){return this.set},getLabel:function(){return this.label}})})();(function(){var d=window.AmCharts;d.RecFill=d.Class({construct:function(a,b,c,e){var h=a.dx,f=a.dy,g=a.orientation,k=0;if(c<b){var l=b;b=c;c=l}var m=e.fillAlpha;isNaN(m)&&(m=0);var l=a.chart.container,p=e.fillColor;"V"==g?(b=d.fitToBounds(b,0,a.height),c=d.fitToBounds(c,0,a.height)):(b=d.fitToBounds(b,0,a.width),c=d.fitToBounds(c,0,a.width));c-=b;isNaN(c)&&(c=4,k=2,m=0);0>c&&"object"==typeof p&&(p=p.join(",").split(",").reverse());"V"==g?(g=d.rect(l,a.width,c,p,m),g.translate(h,b-k+f)):(g=d.rect(l,c,a.height,p,m),g.translate(b-k+h,f));d.setCN(a.chart,g,"guide-fill");e.id&&d.setCN(a.chart,g,"guide-fill-"+e.id);this.set=l.set([g])},graphics:function(){return this.set},getLabel:function(){}})})();(function(){var d=window.AmCharts;d.AmChart=d.Class({construct:function(a){this.svgIcons=this.tapToActivate=!0;this.theme=a;this.classNamePrefix="amcharts";this.addClassNames=!1;this.version="3.21.3";d.addChart(this);this.createEvents("buildStarted","dataUpdated","init","rendered","drawn","failed","resized","animationFinished");this.height=this.width="100%";this.dataChanged=!0;this.chartCreated=!1;this.previousWidth=this.previousHeight=0;this.backgroundColor="#FFFFFF";this.borderAlpha=this.backgroundAlpha=0;this.color=this.borderColor="#000000";this.fontFamily="Verdana";this.fontSize=11;this.usePrefixes=!1;this.autoResize=!0;this.autoDisplay=!1;this.addCodeCredits=this.accessible=!0;this.touchStartTime=this.touchClickDuration=0;this.precision=-1;this.percentPrecision=2;this.decimalSeparator=".";this.thousandsSeparator=",";this.labels=[];this.allLabels=[];this.titles=[];this.marginRight=this.marginLeft=this.autoMarginOffset=0;this.timeOuts=[];this.creditsPosition="top-left";var b=document.createElement("div"),c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.chartDiv=b;b=document.createElement("div");c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.legendDiv=b;this.titleHeight=0;this.hideBalloonTime=150;this.handDrawScatter=2;this.cssScale=this.handDrawThickness=1;this.cssAngle=0;this.prefixesOfBigNumbers=[{number:1E3,prefix:"k"},{number:1E6,prefix:"M"},{number:1E9,prefix:"G"},{number:1E12,prefix:"T"},{number:1E15,prefix:"P"},{number:1E18,prefix:"E"},{number:1E21,prefix:"Z"},{number:1E24,prefix:"Y"}];this.prefixesOfSmallNumbers=[{number:1E-24,prefix:"y"},{number:1E-21,prefix:"z"},{number:1E-18,prefix:"a"},{number:1E-15,prefix:"f"},{number:1E-12,prefix:"p"},{number:1E-9,prefix:"n"},{number:1E-6,prefix:"\u03bc"},{number:.001,prefix:"m"}];this.panEventsEnabled=!0;this.product="amcharts";this.animations=[];this.balloon=new d.AmBalloon(this.theme);this.balloon.chart=this;this.processTimeout=0;this.processCount=1E3;this.animatable=[];this.langObj={};d.applyTheme(this,a,"AmChart")},drawChart:function(){0<this.realWidth&&0<this.realHeight&&(this.drawBackground(),this.redrawLabels(),this.drawTitles(),this.brr(),this.renderFix(),this.chartDiv&&(this.boundingRect=this.chartDiv.getBoundingClientRect()))},makeAccessible:function(a,b,c){this.accessible&&a&&(c&&a.setAttr("role",c),a.setAttr("aria-label",b))},drawBackground:function(){d.remove(this.background);var a=this.container,b=this.backgroundColor,c=this.backgroundAlpha,e=this.set;d.isModern||0!==c||(c=.001);var h=this.updateWidth();this.realWidth=h;var f=this.updateHeight();this.realHeight=f;b=d.polygon(a,[0,h-1,h-1,0],[0,0,f-1,f-1],b,c,1,this.borderColor,this.borderAlpha);d.setCN(this,b,"bg");this.background=b;e.push(b);if(b=this.backgroundImage)a=a.image(b,0,0,h,f),d.setCN(this,b,"bg-image"),this.bgImg=a,e.push(a)},drawTitles:function(a){var b=this.titles;this.titleHeight=0;if(d.ifArray(b)){var c=20,e;for(e=0;e<b.length;e++){var h=b[e],h=d.processObject(h,d.Title,this.theme);if(!1!==h.enabled){var f=h.color;void 0===f&&(f=this.color);var g=h.size;isNaN(g)&&(g=this.fontSize+2);isNaN(h.alpha);var k=this.marginLeft,l=!0;void 0!==h.bold&&(l=h.bold);f=d.wrappedText(this.container,h.text,f,this.fontFamily,g,"middle",l,this.realWidth-35-this.marginRight-k);f.translate(k+(this.realWidth-this.marginRight-k)/2,c);f.node.style.pointerEvents="none";h.sprite=f;void 0!==h.tabIndex&&f.setAttr("tabindex",h.tabIndex);d.setCN(this,f,"title");h.id&&d.setCN(this,f,"title-"+h.id);f.attr({opacity:h.alpha});c+=f.getBBox().height+ -5;a?f.remove():this.freeLabelsSet.push(f)}}this.titleHeight=c-10}},write:function(a){var b=this;if(b.listeners)for(var c=0;c<b.listeners.length;c++){var e=b.listeners[c];b.addListener(e.event,e.method)}b.fire({type:"buildStarted",chart:b});b.afterWriteTO&&clearTimeout(b.afterWriteTO);0<b.processTimeout?b.afterWriteTO=setTimeout(function(){b.afterWrite.call(b,a)},b.processTimeout):b.afterWrite(a)},afterWrite:function(a){var b;if(b="object"!=typeof a?document.getElementById(a):a){for(;b.firstChild;)b.removeChild(b.firstChild);this.div=b;b.style.overflow="hidden";b.style.textAlign="left";a=this.chartDiv;var c=this.legendDiv,e=this.legend,h=c.style,f=a.style;this.measure();this.previousHeight=this.divRealHeight;this.previousWidth=this.divRealWidth;var g,k=document.createElement("div");g=k.style;g.position="relative";this.containerDiv=k;k.className=this.classNamePrefix+"-main-div";a.className=this.classNamePrefix+"-chart-div";b.appendChild(k);(b=this.exportConfig)&&d.AmExport&&!this.AmExport&&(this.AmExport=new d.AmExport(this,b));this.amExport&&d.AmExport&&(this.AmExport=d.extend(this.amExport,new d.AmExport(this),!0));this.AmExport&&this.AmExport.init&&this.AmExport.init();if(e){e=this.addLegend(e,e.divId);if(e.enabled)switch(h.left=null,h.top=null,h.right=null,f.left=null,f.right=null,f.top=null,h.position="relative",f.position="relative",g.width="100%",g.height="100%",e.position){case"bottom":k.appendChild(a);k.appendChild(c);break;case"top":k.appendChild(c);k.appendChild(a);break;case"absolute":h.position="absolute";f.position="absolute";void 0!==e.left&&(h.left=e.left+"px");void 0!==e.right&&(h.right=e.right+"px");void 0!==e.top&&(h.top=e.top+"px");void 0!==e.bottom&&(h.bottom=e.bottom+"px");e.marginLeft=0;e.marginRight=0;k.appendChild(a);k.appendChild(c);break;case"right":h.position="relative";f.position="absolute";k.appendChild(a);k.appendChild(c);break;case"left":h.position="absolute";f.position="relative";k.appendChild(a);k.appendChild(c);break;case"outside":k.appendChild(a)}else k.appendChild(a);this.prevLegendPosition=e.position}else k.appendChild(a);this.listenersAdded||(this.addListeners(),this.listenersAdded=!0);(this.mouseWheelScrollEnabled||this.mouseWheelZoomEnabled)&&d.addWheelListeners();this.initChart()}},createLabelsSet:function(){d.remove(this.labelsSet);this.labelsSet=this.container.set();this.freeLabelsSet.push(this.labelsSet)},initChart:function(){this.balloon=d.processObject(this.balloon,d.AmBalloon,this.theme);window.AmCharts_path&&(this.path=window.AmCharts_path);void 0===this.path&&(this.path=d.getPath());void 0===this.path&&(this.path="amcharts/");this.path=d.normalizeUrl(this.path);void 0===this.pathToImages&&(this.pathToImages=this.path+"images/");this.initHC||(d.callInitHandler(this),this.initHC=!0);d.applyLang(this.language,this);var a=this.numberFormatter;a&&(isNaN(a.precision)||(this.precision=a.precision),void 0!==a.thousandsSeparator&&(this.thousandsSeparator=a.thousandsSeparator),void 0!==a.decimalSeparator&&(this.decimalSeparator=a.decimalSeparator));(a=this.percentFormatter)&&!isNaN(a.precision)&&(this.percentPrecision=a.precision);this.nf={precision:this.precision,thousandsSeparator:this.thousandsSeparator,decimalSeparator:this.decimalSeparator};this.pf={precision:this.percentPrecision,thousandsSeparator:this.thousandsSeparator,decimalSeparator:this.decimalSeparator};this.destroy();(a=this.container)?(a.container.innerHTML="",a.width=this.realWidth,a.height=this.realHeight,a.addDefs(this),this.chartDiv.appendChild(a.container)):a=new d.AmDraw(this.chartDiv,this.realWidth,this.realHeight,this);this.container=a;this.extension=".png";this.svgIcons&&d.SVG&&(this.extension=".svg");this.checkDisplay();this.checkTransform(this.div);a.chart=this;d.VML||d.SVG?(a.handDrawn=this.handDrawn,a.handDrawScatter=this.handDrawScatter,a.handDrawThickness=this.handDrawThickness,d.remove(this.set),this.set=a.set(),d.remove(this.gridSet),this.gridSet=a.set(),d.remove(this.cursorLineSet),this.cursorLineSet=a.set(),d.remove(this.graphsBehindSet),this.graphsBehindSet=a.set(),d.remove(this.bulletBehindSet),this.bulletBehindSet=a.set(),d.remove(this.columnSet),this.columnSet=a.set(),d.remove(this.graphsSet),this.graphsSet=a.set(),d.remove(this.trendLinesSet),this.trendLinesSet=a.set(),d.remove(this.axesSet),this.axesSet=a.set(),d.remove(this.cursorSet),this.cursorSet=a.set(),d.remove(this.scrollbarsSet),this.scrollbarsSet=a.set(),d.remove(this.bulletSet),this.bulletSet=a.set(),d.remove(this.freeLabelsSet),this.freeLabelsSet=a.set(),d.remove(this.axesLabelsSet),this.axesLabelsSet=a.set(),d.remove(this.balloonsSet),this.balloonsSet=a.set(),d.remove(this.plotBalloonsSet),this.plotBalloonsSet=a.set(),d.remove(this.zoomButtonSet),this.zoomButtonSet=a.set(),d.remove(this.zbSet),this.zbSet=null,d.remove(this.linkSet),this.linkSet=a.set()):this.fire({type:"failed",chart:this})},premeasure:function(){var a=this.div;if(a){try{this.boundingRect=this.chartDiv.getBoundingClientRect()}catch(e){}var b=a.offsetWidth,c=a.offsetHeight;a.clientHeight&&(b=a.clientWidth,c=a.clientHeight);if(b!=this.mw||c!=this.mh)this.mw=b,this.mh=c,this.measure()}},measure:function(){var a=this.div;if(a){var b=this.chartDiv,c=a.offsetWidth,e=a.offsetHeight,h=this.container;a.clientHeight&&(c=a.clientWidth,e=a.clientHeight);var e=Math.round(e),c=Math.round(c),a=Math.round(d.toCoordinate(this.width,c)),f=Math.round(d.toCoordinate(this.height,e));(c!=this.previousWidth||e!=this.previousHeight)&&0<a&&0<f&&(b.style.width=a+"px",b.style.height=f+"px",b.style.padding=0,h&&h.setSize(a,f),this.balloon=d.processObject(this.balloon,d.AmBalloon,this.theme));this.balloon&&this.balloon.setBounds&&this.balloon.setBounds(2,2,a-2,f);this.updateWidth();this.balloon.chart=this;this.realWidth=a;this.realHeight=f;this.divRealWidth=c;this.divRealHeight=e}},checkDisplay:function(){if(this.autoDisplay&&this.container){var a=d.rect(this.container,10,10),b=a.getBBox();0===b.width&&0===b.height&&(this.divRealHeight=this.divRealWidth=this.realHeight=this.realWidth=0,this.previousWidth=this.previousHeight=NaN);a.remove()}},checkTransform:function(a){if(this.autoTransform&&window.getComputedStyle&&a){if(a.style){var b=window.getComputedStyle(a,null);if(b&&(b=b.getPropertyValue("-webkit-transform")||b.getPropertyValue("-moz-transform")||b.getPropertyValue("-ms-transform")||b.getPropertyValue("-o-transform")||b.getPropertyValue("transform"))&&"none"!==b){var c=b.split("(")[1].split(")")[0].split(","),b=c[0],c=c[1],b=Math.sqrt(b*b+c*c);isNaN(b)||(this.cssScale*=b)}}a.parentNode&&this.checkTransform(a.parentNode)}},destroy:function(){this.chartDiv.innerHTML="";this.clearTimeOuts();this.legend&&this.legend.destroy()},clearTimeOuts:function(){var a=this.timeOuts;if(a){var b;for(b=0;b<a.length;b++)clearTimeout(a[b])}this.timeOuts=[]},clear:function(a){try{document.removeEventListener("touchstart",this.docfn1,!0),document.removeEventListener("touchend",this.docfn2,!0)}catch(b){}d.callMethod("clear",[this.chartScrollbar,this.scrollbarV,this.scrollbarH,this.chartCursor]);this.chartCursor=this.scrollbarH=this.scrollbarV=this.chartScrollbar=null;this.clearTimeOuts();this.container&&(this.container.remove(this.chartDiv),this.container.remove(this.legendDiv));a||d.removeChart(this);if(a=this.div)for(;a.firstChild;)a.removeChild(a.firstChild);this.legend&&this.legend.destroy();this.AmExport&&this.AmExport.clear&&this.AmExport.clear()},setMouseCursor:function(a){"auto"==a&&d.isNN&&(a="default");this.chartDiv.style.cursor=a;this.legendDiv.style.cursor=a},redrawLabels:function(){this.labels=[];var a=this.allLabels;this.createLabelsSet();var b;for(b=0;b<a.length;b++)this.drawLabel(a[b])},drawLabel:function(a){var b=this;if(b.container&&!1!==a.enabled){a=d.processObject(a,d.Label,b.theme);var c=a.y,e=a.text,h=a.align,f=a.size,g=a.color,k=a.rotation,l=a.alpha,m=a.bold,p=d.toCoordinate(a.x,b.realWidth),c=d.toCoordinate(c,b.realHeight);p||(p=0);c||(c=0);void 0===g&&(g=b.color);isNaN(f)&&(f=b.fontSize);h||(h="start");"left"==h&&(h="start");"right"==h&&(h="end");"center"==h&&(h="middle",k?c=b.realHeight-c+c/2:p=b.realWidth/2-p);void 0===l&&(l=1);void 0===k&&(k=0);c+=f/2;e=d.text(b.container,e,g,b.fontFamily,f,h,m,l);e.translate(p,c);void 0!==a.tabIndex&&e.setAttr("tabindex",a.tabIndex);d.setCN(b,e,"label");a.id&&d.setCN(b,e,"label-"+a.id);0!==k&&e.rotate(k);a.url?(e.setAttr("cursor","pointer"),e.click(function(){d.getURL(a.url,b.urlTarget)})):e.node.style.pointerEvents="none";b.labelsSet.push(e);b.labels.push(e)}},addLabel:function(a,b,c,e,d,f,g,k,l,m){a={x:a,y:b,text:c,align:e,size:d,color:f,alpha:k,rotation:g,bold:l,url:m,enabled:!0};this.container&&this.drawLabel(a);this.allLabels.push(a)},clearLabels:function(){var a=this.labels,b;for(b=a.length-1;0<=b;b--)a[b].remove();this.labels=[];this.allLabels=[]},updateHeight:function(){var a=this.divRealHeight,b=this.legend;if(b){var c=this.legendDiv.offsetHeight,b=b.position;if("top"==b||"bottom"==b){a-=c;if(0>a||isNaN(a))a=0;this.chartDiv.style.height=a+"px"}}return a},updateWidth:function(){var a=this.divRealWidth,b=this.divRealHeight,c=this.legend;if(c){var e=this.legendDiv,d=e.offsetWidth;isNaN(c.width)||(d=c.width);c.ieW&&(d=c.ieW);var f=e.offsetHeight,e=e.style,g=this.chartDiv.style,k=c.position;if(("right"==k||"left"==k)&&void 0===c.divId){a-=d;if(0>a||isNaN(a))a=0;g.width=a+"px";this.balloon&&this.balloon.setBounds&&this.balloon.setBounds(2,2,a-2,this.realHeight);"left"==k?(g.left=d+"px",e.left="0px"):(g.left="0px",e.left=a+"px");b>f&&(e.top=(b-f)/2+"px")}}return a},getTitleHeight:function(){this.drawTitles(!0);return this.titleHeight},addTitle:function(a,b,c,e,d){isNaN(b)&&(b=this.fontSize+2);a={text:a,size:b,color:c,alpha:e, -bold:d,enabled:!0};this.titles.push(a);return a},handleWheel:function(a){var b=0;a||(a=window.event);a.wheelDelta?b=a.wheelDelta/120:a.detail&&(b=-a.detail/3);b&&this.handleWheelReal(b,a.shiftKey);a.preventDefault&&a.preventDefault()},handleWheelReal:function(){},handleDocTouchStart:function(){this.handleMouseMove();this.tmx=this.mouseX;this.tmy=this.mouseY;this.touchStartTime=(new Date).getTime()},handleDocTouchEnd:function(){-.5<this.tmx&&this.tmx<this.divRealWidth+1&&0<this.tmy&&this.tmy<this.divRealHeight?(this.handleMouseMove(),4>Math.abs(this.mouseX-this.tmx)&&4>Math.abs(this.mouseY-this.tmy)?(this.tapped=!0,this.panRequired&&this.panEventsEnabled&&this.chartDiv&&(this.chartDiv.style.msTouchAction="none",this.chartDiv.style.touchAction="none")):this.mouseIsOver||this.resetTouchStyle()):(this.tapped=!1,this.resetTouchStyle())},resetTouchStyle:function(){this.panEventsEnabled&&this.chartDiv&&(this.chartDiv.style.msTouchAction="auto",this.chartDiv.style.touchAction="auto")},checkTouchDuration:function(a){var b=this,c=(new Date).getTime();if(a)if(a.touches)b.isTouchEvent=!0;else if(!b.isTouchEvent)return!0;if(c-b.touchStartTime>b.touchClickDuration)return!0;setTimeout(function(){b.resetTouchDuration()},300)},resetTouchDuration:function(){this.isTouchEvent=!1},checkTouchMoved:function(){if(4<Math.abs(this.mouseX-this.tmx)||4<Math.abs(this.mouseY-this.tmy))return!0},addListeners:function(){var a=this,b=a.chartDiv;document.addEventListener?("ontouchstart"in document.documentElement&&(b.addEventListener("touchstart",function(b){a.handleTouchStart.call(a,b)},!0),b.addEventListener("touchmove",function(b){a.handleMouseMove.call(a,b)},!0),b.addEventListener("touchend",function(b){a.handleTouchEnd.call(a,b)},!0),a.docfn1=function(b){a.handleDocTouchStart.call(a,b)},a.docfn2=function(b){a.handleDocTouchEnd.call(a,b)},document.addEventListener("touchstart",a.docfn1,!0),document.addEventListener("touchend",a.docfn2,!0)),b.addEventListener("mousedown",function(b){a.mouseIsOver=!0;a.handleMouseMove.call(a,b);a.handleMouseDown.call(a,b);a.handleDocTouchStart.call(a,b)},!0),b.addEventListener("mouseover",function(b){a.handleMouseOver.call(a,b)},!0),b.addEventListener("mouseout",function(b){a.handleMouseOut.call(a,b)},!0),b.addEventListener("mouseup",function(b){a.handleDocTouchEnd.call(a,b)},!0)):(b.attachEvent("onmousedown",function(b){a.handleMouseDown.call(a,b)}),b.attachEvent("onmouseover",function(b){a.handleMouseOver.call(a,b)}),b.attachEvent("onmouseout",function(b){a.handleMouseOut.call(a,b)}))},dispDUpd:function(){this.skipEvents||(this.dispatchDataUpdated&&(this.dispatchDataUpdated=!1,this.fire({type:"dataUpdated",chart:this})),this.chartCreated||(this.chartCreated=!0,this.fire({type:"init",chart:this})),this.chartRendered||(this.fire({type:"rendered",chart:this}),this.chartRendered=!0),this.fire({type:"drawn",chart:this}));this.skipEvents=!1},validateSize:function(){var a=this;a.premeasure();a.checkDisplay();a.cssScale=1;a.cssAngle=0;a.checkTransform(a.div);if(a.divRealWidth!=a.previousWidth||a.divRealHeight!=a.previousHeight){var b=a.legend;if(0<a.realWidth&&0<a.realHeight){a.sizeChanged=!0;if(b){a.legendInitTO&&clearTimeout(a.legendInitTO);var c=setTimeout(function(){b.invalidateSize()},10);a.timeOuts.push(c);a.legendInitTO=c}a.marginsUpdated=!1;clearTimeout(a.initTO);c=setTimeout(function(){a.initChart()},10);a.timeOuts.push(c);a.initTO=c}a.renderFix();b&&b.renderFix&&b.renderFix();clearTimeout(a.resizedTO);a.resizedTO=setTimeout(function(){a.fire({type:"resized",chart:a})},10);a.previousHeight=a.divRealHeight;a.previousWidth=a.divRealWidth}},invalidateSize:function(){this.previousHeight=this.previousWidth=NaN;this.invalidateSizeReal()},invalidateSizeReal:function(){var a=this;a.marginsUpdated=!1;clearTimeout(a.validateTO);var b=setTimeout(function(){a.validateSize()},5);a.timeOuts.push(b);a.validateTO=b},validateData:function(a){this.chartCreated&&(this.dataChanged=!0,this.marginsUpdated=!1,this.initChart(a))},validateNow:function(a,b){this.initTO&&clearTimeout(this.initTO);a&&(this.dataChanged=!0,this.marginsUpdated=!1);this.skipEvents=b;this.chartRendered=!1;var c=this.legend;c&&c.position!=this.prevLegendPosition&&(this.previousWidth=this.mw=0,c.invalidateSize&&(c.invalidateSize(),this.validateSize()));this.write(this.div)},showItem:function(a){a.hidden=!1;this.initChart()},hideItem:function(a){a.hidden=!0;this.initChart()},hideBalloon:function(){var a=this;clearTimeout(a.hoverInt);clearTimeout(a.balloonTO);a.hoverInt=setTimeout(function(){a.hideBalloonReal.call(a)},a.hideBalloonTime)},cleanChart:function(){},hideBalloonReal:function(){var a=this.balloon;a&&a.hide&&a.hide()},showBalloon:function(a,b,c,e,d){var f=this;clearTimeout(f.balloonTO);clearTimeout(f.hoverInt);f.balloonTO=setTimeout(function(){f.showBalloonReal.call(f,a,b,c,e,d)},1)},showBalloonReal:function(a,b,c,e,d){this.handleMouseMove();var f=this.balloon;f.enabled&&(f.followCursor(!1),f.changeColor(b),!c||f.fixedPosition?(f.setPosition(e,d),isNaN(e)||isNaN(d)?f.followCursor(!0):f.followCursor(!1)):f.followCursor(!0),a&&f.showBalloon(a))},handleMouseOver:function(){this.outTO&&clearTimeout(this.outTO);d.resetMouseOver();this.mouseIsOver=!0},handleMouseOut:function(){var a=this;d.resetMouseOver();a.outTO&&clearTimeout(a.outTO);a.outTO=setTimeout(function(){a.handleMouseOutReal()},10)},handleMouseOutReal:function(){this.mouseIsOver=!1},handleMouseMove:function(a){a||(a=window.event);this.mouse2Y=this.mouse2X=NaN;var b,c,e,d;if(a){if(a.touches){var f=a.touches.item(1);f&&this.panEventsEnabled&&this.boundingRect&&(e=f.clientX-this.boundingRect.left,d=f.clientY-this.boundingRect.top);a=a.touches.item(0);if(!a)return}else this.wasTouched=!1;this.boundingRect&&a.clientX&&(b=a.clientX-this.boundingRect.left,c=a.clientY-this.boundingRect.top);isNaN(e)?this.mouseX=b:(this.mouseX=Math.min(b,e),this.mouse2X=Math.max(b,e));isNaN(d)?this.mouseY=c:(this.mouseY=Math.min(c,d),this.mouse2Y=Math.max(c,d));this.autoTransform&&(this.mouseX/=this.cssScale,this.mouseY/=this.cssScale)}},handleTouchStart:function(a){this.hideBalloonReal();a&&(a.touches&&this.tapToActivate&&!this.tapped||!this.panRequired)||(this.handleMouseMove(a),this.handleMouseDown(a))},handleTouchEnd:function(a){this.wasTouched=!0;this.handleMouseMove(a);d.resetMouseOver();this.handleReleaseOutside(a)},handleReleaseOutside:function(){this.handleDocTouchEnd.call(this)},handleMouseDown:function(a){d.resetMouseOver();this.mouseIsOver=!0;a&&a.preventDefault&&(this.panEventsEnabled?a.preventDefault():a.touches||a.preventDefault())},addLegend:function(a,b){a=d.processObject(a,d.AmLegend,this.theme);a.divId=b;a.ieW=0;var c;c="object"!=typeof b&&b?document.getElementById(b):b;this.legend=a;a.chart=this;c?(a.div=c,a.position="outside",a.autoMargins=!1):a.div=this.legendDiv;return a},removeLegend:function(){this.legend=void 0;this.previousWidth=0;this.legendDiv.innerHTML=""},handleResize:function(){(d.isPercents(this.width)||d.isPercents(this.height))&&this.invalidateSizeReal();this.renderFix()},renderFix:function(){if(!d.VML){var a=this.container;a&&a.renderFix()}},getSVG:function(){if(d.hasSVG)return this.container},animate:function(a,b,c,e,h,f,g){a["an_"+b]&&d.removeFromArray(this.animations,a["an_"+b]);c={obj:a,frame:0,attribute:b,from:c,to:e,time:h,effect:f,suffix:g};a["an_"+b]=c;this.animations.push(c);return c},setLegendData:function(a){var b=this.legend;b&&b.setData(a)},stopAnim:function(a){d.removeFromArray(this.animations,a)},updateAnimations:function(){var a;this.container&&this.container.update();if(this.animations)for(a=this.animations.length-1;0<=a;a--){var b=this.animations[a],c=d.updateRate*b.time,e=b.frame+1,h=b.obj,f=b.attribute;if(e<=c){b.frame++;var g=Number(b.from),k=Number(b.to)-g,c=d[b.effect](0,e,g,k,c);0===k?(this.animations.splice(a,1),h.node.style[f]=Number(b.to)+b.suffix):h.node.style[f]=c+b.suffix}else h.node.style[f]=Number(b.to)+b.suffix,h.animationFinished=!0,this.animations.splice(a,1)}},update:function(){this.updateAnimations();var a=this.animatable;if(0<a.length){for(var b=!0,c=a.length-1;0<=c;c--){var e=a[c];e&&(e.animationFinished?a.splice(c,1):b=!1)}b&&(this.fire({type:"animationFinished",chart:this}),this.animatable=[])}},inIframe:function(){try{return window.self!==window.top}catch(a){return!0}},brr:function(){if(false){var a="amcharts.com",b=window.location.hostname.split("."),c;2<=b.length&&(c=b[b.length-2]+"."+b[b.length-1]);this.amLink&&(b=this.amLink.parentNode)&&b.removeChild(this.amLink);b=this.creditsPosition;if(c!=a||!0===this.inIframe()){var a="http://www."+a,e=c=0,d=this.realWidth,f=this.realHeight,g=this.type;if("serial"==g||"xy"==g||"gantt"==g)c=this.marginLeftReal,e=this.marginTopReal,d=c+this.plotAreaWidth,f=e+this.plotAreaHeight;var g=a+"/javascript-charts/",k="JavaScript charts",l="JS chart by amCharts";"ammap"==this.product&&(g=a+"/javascript-maps/",k="Interactive JavaScript maps",l="JS map by amCharts");a=document.createElement("a");l=document.createTextNode(l);a.setAttribute("href",g);a.setAttribute("title",k);this.urlTarget&&a.setAttribute("target",this.urlTarget);a.appendChild(l);this.chartDiv.appendChild(a);this.amLink=a;g=a.style;g.position="absolute";g.textDecoration="none";g.color=this.color;g.fontFamily=this.fontFamily;g.fontSize="11px";g.opacity=.7;g.display="block";var k=a.offsetWidth,a=a.offsetHeight,l=5+c,m=e+5;"bottom-left"==b&&(l=5+c,m=f-a-3);"bottom-right"==b&&(l=d-k-5,m=f-a-3);"top-right"==b&&(l=d-k-5,m=e+5);g.left=l+"px";g.top=m+"px"}}}});d.Slice=d.Class({construct:function(){}});d.SerialDataItem=d.Class({construct:function(){}});d.GraphDataItem=d.Class({construct:function(){}});d.Guide=d.Class({construct:function(a){this.cname="Guide";d.applyTheme(this,a,this.cname)}});d.Title=d.Class({construct:function(a){this.cname="Title";d.applyTheme(this,a,this.cname)}});d.Label=d.Class({construct:function(a){this.cname="Label";d.applyTheme(this,a,this.cname)}})})();(function(){var d=window.AmCharts;d.AmGraph=d.Class({construct:function(a){this.cname="AmGraph";this.createEvents("rollOverGraphItem","rollOutGraphItem","clickGraphItem","doubleClickGraphItem","rightClickGraphItem","clickGraph","rollOverGraph","rollOutGraph");this.type="line";this.stackable=!0;this.columnCount=1;this.columnIndex=0;this.centerCustomBullets=this.showBalloon=!0;this.maxBulletSize=50;this.minBulletSize=4;this.balloonText="[[value]]";this.hidden=this.scrollbar=this.animationPlayed=!1;this.pointPosition="middle";this.depthCount=1;this.includeInMinMax=!0;this.negativeBase=0;this.visibleInLegend=!0;this.showAllValueLabels=!1;this.showBulletsAt=this.showBalloonAt="close";this.lineThickness=1;this.dashLength=0;this.connect=!0;this.lineAlpha=1;this.bullet="none";this.bulletBorderThickness=2;this.bulletBorderAlpha=0;this.bulletAlpha=1;this.bulletSize=8;this.cornerRadiusTop=this.hideBulletsCount=this.bulletOffset=0;this.cursorBulletAlpha=1;this.gradientOrientation="vertical";this.dy=this.dx=0;this.periodValue="";this.clustered=!0;this.periodSpan=1;this.accessibleLabel="[[title]] [[category]] [[value]]";this.accessibleSkipText="Press enter to skip [[title]]";this.y=this.x=0;this.switchable=!0;this.tcc=this.minDistance=1;this.labelRotation=0;this.labelAnchor="auto";this.labelOffset=3;this.bcn="graph-";this.dateFormat="MMM DD, YYYY";this.noRounding=!0;d.applyTheme(this,a,this.cname)},init:function(){this.createBalloon()},draw:function(){var a=this.chart;a.isRolledOverBullet=!1;var b=a.type;if(a.drawGraphs){isNaN(this.precision)||(this.numberFormatter?this.numberFormatter.precision=this.precision:this.numberFormatter={precision:this.precision,decimalSeparator:a.decimalSeparator,thousandsSeparator:a.thousandsSeparator});var c=a.container;this.container=c;this.destroy();var e=c.set();this.set=e;e.translate(this.x,this.y);var h=c.set();this.bulletSet=h;h.translate(this.x,this.y);this.behindColumns?(a.graphsBehindSet.push(e),a.bulletBehindSet.push(h)):(a.graphsSet.push(e),a.bulletSet.push(h));var f=this.bulletAxis;d.isString(f)&&(this.bulletAxis=a.getValueAxisById(f));c=c.set();d.remove(this.columnsSet);this.columnsSet=c;d.setCN(a,e,"graph-"+this.type);d.setCN(a,e,"graph-"+this.id);d.setCN(a,h,"graph-"+this.type);d.setCN(a,h,"graph-"+this.id);this.columnsArray=[];this.ownColumns=[];this.allBullets=[];this.animationArray=[];h=this.labelPosition;h||(f=this.valueAxis.stackType,h="top","column"==this.type&&(a.rotate&&(h="right"),"100%"==f||"regular"==f)&&(h="middle"),this.labelPosition=h);d.ifArray(this.data)&&(a=!1,"xy"==b?this.xAxis.axisCreated&&this.yAxis.axisCreated&&(a=!0):this.valueAxis.axisCreated&&(a=!0),!this.hidden&&a&&this.createGraph());e.push(c)}},createGraph:function(){var a=this,b=a.chart;a.startAlpha=b.startAlpha;a.seqAn=b.sequencedAnimation;a.baseCoord=a.valueAxis.baseCoord;void 0===a.fillAlphas&&(a.fillAlphas=0);a.bulletColorR=a.bulletColor;void 0===a.bulletColorR&&(a.bulletColorR=a.lineColorR,a.bulletColorNegative=a.negativeLineColor);void 0===a.bulletAlpha&&(a.bulletAlpha=a.lineAlpha);if("step"==c||d.VML)a.noRounding=!1;var c=b.type;"gantt"==c&&(c="serial");clearTimeout(a.playedTO);if(!isNaN(a.valueAxis.min)&&!isNaN(a.valueAxis.max)){switch(c){case"serial":a.categoryAxis&&(a.createSerialGraph(),"candlestick"==a.type&&1>a.valueAxis.minMaxMultiplier&&a.positiveClip(a.set));break;case"radar":a.createRadarGraph();break;case"xy":a.createXYGraph()}a.playedTO=setTimeout(function(){a.setAnimationPlayed.call(a)},500*a.chart.startDuration)}},setAnimationPlayed:function(){this.animationPlayed=!0},createXYGraph:function(){var a=[],b=[],c=this.xAxis,e=this.yAxis;this.pmh=e.height;this.pmw=c.width;this.pmy=this.pmx=0;var d;for(d=this.start;d<=this.end;d++){var f=this.data[d].axes[c.id].graphs[this.id],g=f.values,k=g.x,l=g.y,g=c.getCoordinate(k,this.noRounding),m=e.getCoordinate(l,this.noRounding);if(!isNaN(k)&&!isNaN(l)&&(a.push(g),b.push(m),f.x=g,f.y=m,k=this.createBullet(f,g,m,d),l=this.labelText)){var l=this.createLabel(f,l),p=0;k&&(p=k.size);this.positionLabel(f,g,m,l,p)}}this.drawLineGraph(a,b);this.launchAnimation()},createRadarGraph:function(){var a=this.valueAxis.stackType,b=[],c=[],e=[],d=[],f,g,k,l,m;for(m=this.start;m<=this.end;m++){var p=this.data[m].axes[this.valueAxis.id].graphs[this.id],q,n;"none"==a||"3d"==a?q=p.values.value:(q=p.values.close,n=p.values.open);if(isNaN(q))this.connect||(this.drawLineGraph(b,c,e,d),b=[],c=[],e=[],d=[]);else{var t=this.valueAxis.getCoordinate(q,this.noRounding)-this.height,t=t*this.valueAxis.rMultiplier,r=-360/(this.end-this.start+1)*m;"middle"==this.valueAxis.pointPosition&&(r-=180/(this.end-this.start+1));q=t*Math.sin(r/180*Math.PI);t*=Math.cos(r/180*Math.PI);b.push(q);c.push(t);if(!isNaN(n)){var w=this.valueAxis.getCoordinate(n,this.noRounding)-this.height,w=w*this.valueAxis.rMultiplier,z=w*Math.sin(r/180*Math.PI),r=w*Math.cos(r/180*Math.PI);e.push(z);d.push(r);isNaN(k)&&(k=z);isNaN(l)&&(l=r)}r=this.createBullet(p,q,t,m);p.x=q;p.y=t;if(z=this.labelText)z=this.createLabel(p,z),w=0,r&&(w=r.size),this.positionLabel(p,q,t,z,w);isNaN(f)&&(f=q);isNaN(g)&&(g=t)}}b.push(f);c.push(g);isNaN(k)||(e.push(k),d.push(l));this.drawLineGraph(b,c,e,d);this.launchAnimation()},positionLabel:function(a,b,c,e,d){if(e){var f=this.chart,g=this.valueAxis,k="middle",l=!1,m=this.labelPosition,p=e.getBBox(),q=this.chart.rotate,n=a.isNegative,t=this.fontSize;void 0===t&&(t=this.chart.fontSize);c-=p.height/2-t/2-1;void 0!==a.labelIsNegative&&(n=a.labelIsNegative);switch(m){case"right":m=q?n?"left":"right":"right";break;case"top":m=q?"top":n?"bottom":"top";break;case"bottom":m=q?"bottom":n?"top":"bottom";break;case"left":m=q?n?"right":"left":"left"}var t=a.columnGraphics,r=0,w=0;t&&(r=t.x,w=t.y);var z=this.labelOffset;switch(m){case"right":k="start";b+=d/2+z;break;case"top":c=g.reversed?c+(d/2+p.height/2+z):c-(d/2+p.height/2+z);break;case"bottom":c=g.reversed?c-(d/2+p.height/2+z):c+(d/2+p.height/2+z);break;case"left":k="end";b-=d/2+z;break;case"inside":"column"==this.type&&(l=!0,q?n?(k="end",b=r-3-z):(k="start",b=r+3+z):c=n?w+7+z:w-10-z);break;case"middle":"column"==this.type&&(l=!0,q?b-=(b-r)/2+z-3:c-=(c-w)/2+z-3)}"auto"!=this.labelAnchor&&(k=this.labelAnchor);e.attr({"text-anchor":k});this.labelRotation&&e.rotate(this.labelRotation);e.translate(b,c);!this.showAllValueLabels&&t&&l&&(p=e.getBBox(),p.height>a.columnHeight||p.width>a.columnWidth)&&(e.remove(),e=null);if(e&&"radar"!=f.type)if(q){if(0>c||c>this.height)e.remove(),e=null;!this.showAllValueLabels&&e&&(0>b||b>this.width)&&(e.remove(),e=null)}else{if(0>b||b>this.width)e.remove(), -e=null;!this.showAllValueLabels&&e&&(0>c||c>this.height)&&(e.remove(),e=null)}e&&this.allBullets.push(e);return e}},getGradRotation:function(){var a=270;"horizontal"==this.gradientOrientation&&(a=0);return this.gradientRotation=a},createSerialGraph:function(){this.dashLengthSwitched=this.fillColorsSwitched=this.lineColorSwitched=void 0;var a=this.chart,b=this.id,c=this.index,e=this.data,h=this.chart.container,f=this.valueAxis,g=this.type,k=this.columnWidthReal,l=this.showBulletsAt;isNaN(this.columnWidth)||(k=this.columnWidth);isNaN(k)&&(k=.8);var m=this.useNegativeColorIfDown,p=this.width,q=this.height,n=this.y,t=this.rotate,r=this.columnCount,w=d.toCoordinate(this.cornerRadiusTop,k/2),z=this.connect,x=[],u=[],A,y,B,D,C=this.chart.graphs.length,I,H=this.dx/this.tcc,Q=this.dy/this.tcc,M=f.stackType,P=this.start,ia=this.end,J=this.scrollbar,aa="graph-column-";J&&(aa="scrollbar-graph-column-");var ma=this.categoryAxis,na=this.baseCoord,Pa=this.negativeBase,Z=this.columnIndex,da=this.lineThickness,X=this.lineAlpha,xa=this.lineColorR,ea=this.dashLength,fa=this.set,Ba,ga=this.getGradRotation(),V=this.chart.columnSpacing,Y=ma.cellWidth,Da=(Y*k-r)/r;V>Da&&(V=Da);var G,v,oa,ha=q,Qa=p,ca=0,tb=0,ub=0,vb=0,gb=0,hb=0,wb=this.fillColorsR,Ra=this.negativeFillColors,Ja=this.negativeLineColor,Ya=this.fillAlphas,Za=this.negativeFillAlphas;"object"==typeof Ya&&(Ya=Ya[0]);"object"==typeof Za&&(Za=Za[0]);var xb=this.noRounding;"step"==g&&(xb=!1);var ib=f.getCoordinate(f.min);f.logarithmic&&(ib=f.getCoordinate(f.minReal));this.minCoord= -ib;this.resetBullet&&(this.bullet="none");if(!(J||"line"!=g&&"smoothedLine"!=g&&"step"!=g||(1==e.length&&"step"!=g&&"none"==this.bullet&&(this.bullet="round",this.resetBullet=!0),!Ra&&void 0==Ja||m))){var Ua=Pa;Ua>f.max&&(Ua=f.max);Ua<f.min&&(Ua=f.min);f.logarithmic&&(Ua=f.minReal);var Ka=f.getCoordinate(Ua),Mb=f.getCoordinate(f.max);t?(ha=q,Qa=Math.abs(Mb-Ka),ub=q,vb=Math.abs(ib-Ka),hb=tb=0,f.reversed?(ca=0,gb=Ka):(ca=Ka,gb=0)):(Qa=p,ha=Math.abs(Mb-Ka),vb=p,ub=Math.abs(ib-Ka),gb=ca=0,f.reversed?(hb=n,tb=Ka):hb=Ka)}var La=Math.round;this.pmx=La(ca);this.pmy=La(tb);this.pmh=La(ha);this.pmw=La(Qa);this.nmx=La(gb);this.nmy=La(hb);this.nmh=La(ub);this.nmw=La(vb);d.isModern||(this.nmy=this.nmx=0,this.nmh=this.height);this.clustered||(r=1);k="column"==g?(Y*k-V*(r-1))/r:Y*k;1>k&&(k=1);var Nb=this.fixedColumnWidth;isNaN(Nb)||(k=Nb);var L;if("line"==g||"step"==g||"smoothedLine"==g){if(0<P){for(L=P-1;-1<L;L--)if(G=e[L],v=G.axes[f.id].graphs[b],oa=v.values.value,!isNaN(oa)){P=L;break}if(this.lineColorField)for(L= -P;-1<L;L--)if(G=e[L],v=G.axes[f.id].graphs[b],v.lineColor){this.lineColorSwitched=v.lineColor;void 0===this.bulletColor&&(this.bulletColorSwitched=this.lineColorSwitched);break}if(this.fillColorsField)for(L=P;-1<L;L--)if(G=e[L],v=G.axes[f.id].graphs[b],v.fillColors){this.fillColorsSwitched=v.fillColors;break}if(this.dashLengthField)for(L=P;-1<L;L--)if(G=e[L],v=G.axes[f.id].graphs[b],!isNaN(v.dashLength)){this.dashLengthSwitched=v.dashLength;break}}if(ia<e.length-1)for(L=ia+1;L<e.length;L++)if(G=e[L],v=G.axes[f.id].graphs[b],oa=v.values.value,!isNaN(oa)){ia=L;break}}ia<e.length-1&&ia++;var T=[],U=[],Ma=!1;if("line"==g||"step"==g||"smoothedLine"==g)if(this.stackable&&"regular"==M||"100%"==M||this.fillToGraph)Ma=!0;var Ob=this.noStepRisers,jb=-1E3,kb=-1E3,lb=this.minDistance,Sa=!0,$a=!1;for(L=P;L<=ia;L++){G=e[L];v=G.axes[f.id].graphs[b];v.index=L;var ab,Ta=NaN;if(m&&void 0==this.openField)for(var yb=L+1;yb<e.length&&(!e[yb]||!(ab=e[L+1].axes[f.id].graphs[b])||!ab.values||(Ta=ab.values.value,isNaN(Ta)));yb++);var S,R,K,ba,ja=NaN,E=NaN,F=NaN,O=NaN,N=NaN,qa=NaN,ra=NaN,sa=NaN,ta=NaN,ya=NaN,Ea=NaN,ka=NaN,la=NaN,W=NaN,zb=NaN,Ab=NaN,ua=NaN,va=void 0,Na=wb,Va=Ya,Ha=xa,Ca,za,Bb=this.proCandlesticks,mb=this.topRadius,Fa=q-1,pa=p-1,bb=this.pattern;void 0!=v.pattern&&(bb=v.pattern);isNaN(v.alpha)||(Va=v.alpha);isNaN(v.dashLength)||(ea=v.dashLength);var Ia=v.values;f.recalculateToPercents&&(Ia=v.percents);"none"==M&&(Z=isNaN(v.columnIndex)?this.columnIndex:v.columnIndex);if(Ia){W=this.stackable&&"none"!=M&&"3d"!=M?Ia.close:Ia.value;if("candlestick"==g||"ohlc"==g)W=Ia.close,Ab=Ia.low,ra=f.getCoordinate(Ab),zb=Ia.high,ta=f.getCoordinate(zb);ua=Ia.open;F=f.getCoordinate(W,xb);isNaN(ua)||(N=f.getCoordinate(ua,xb),m&&"regular"!=M&&"100%"!=M&&(Ta=ua,ua=N=NaN));m&&(void 0==this.openField?ab&&(ab.isNegative=Ta<W?!0:!1,isNaN(Ta)&&(v.isNegative=!Sa)):v.isNegative=Ta>W?!0:!1);if(!J)switch(this.showBalloonAt){case"close":v.y=F;break;case"open":v.y=N;break;case"high":v.y=ta;break;case"low":v.y=ra}var ja=G.x[ma.id],Wa=this.periodSpan-1;"step"!=g||isNaN(G.cellWidth)||(Y=G.cellWidth);var wa=Math.floor(Y/2)+Math.floor(Wa*Y/2),Ga=wa,nb=0;"left"==this.stepDirection&&(nb=(2*Y+Wa*Y)/2,ja-=nb);"center"==this.stepDirection&&(nb=Y/2,ja-=nb);"start"==this.pointPosition&&(ja-=Y/2+Math.floor(Wa*Y/2),wa=0,Ga=Math.floor(Y)+Math.floor(Wa*Y));"end"==this.pointPosition&&(ja+=Y/2+Math.floor(Wa*Y/2),wa=Math.floor(Y)+Math.floor(Wa*Y),Ga=0);if(Ob){var Cb=this.columnWidth;isNaN(Cb)||(wa*=Cb,Ga*=Cb)}J||(v.x=ja);-1E5>ja&&(ja=-1E5); -ja>p+1E5&&(ja=p+1E5);t?(E=F,O=N,N=F=ja,isNaN(ua)&&!this.fillToGraph&&(O=na),qa=ra,sa=ta):(O=E=ja,isNaN(ua)&&!this.fillToGraph&&(N=na));if(!Bb&&W<ua||Bb&&W<Ba)v.isNegative=!0,Ra&&(Na=Ra),Za&&(Va=Za),void 0!=Ja&&(Ha=Ja);$a=!1;isNaN(W)||(m?W>Ta?(Sa&&($a=!0),Sa=!1):(Sa||($a=!0),Sa=!0):v.isNegative=W<Pa?!0:!1,Ba=W);var Pb=!1;J&&a.chartScrollbar.ignoreCustomColors&&(Pb=!0);Pb||(void 0!=v.color&&(Na=v.color),v.fillColors&&(Na=v.fillColors));F=d.fitToBounds(F,-3E4,3E4);switch(g){case"line":if(isNaN(W))z||(this.drawLineGraph(x,u,T,U),x=[],u=[],T=[],U=[]);else{if(Math.abs(E-jb)>=lb||Math.abs(F-kb)>=lb)x.push(E),u.push(F),jb=E,kb=F;ya=E;Ea=F;ka=E;la=F;!Ma||isNaN(N)||isNaN(O)||(T.push(O),U.push(N));if($a||void 0!=v.lineColor&&v.lineColor!=this.lineColorSwitched||void 0!=v.fillColors&&v.fillColors!=this.fillColorsSwitched||!isNaN(v.dashLength))this.drawLineGraph(x,u,T,U),x=[E],u=[F],T=[],U=[],!Ma||isNaN(N)||isNaN(O)||(T.push(O),U.push(N)),m?(Sa?(this.lineColorSwitched=xa,this.fillColorsSwitched=wb):(this.lineColorSwitched=Ja,this.fillColorsSwitched=Ra),void 0===this.bulletColor&&(this.bulletColorSwitched=xa)):(this.lineColorSwitched=v.lineColor,this.fillColorsSwitched=v.fillColors,void 0===this.bulletColor&&(this.bulletColorSwitched=this.lineColorSwitched)),this.dashLengthSwitched=v.dashLength;v.gap&&(this.drawLineGraph(x,u,T,U),x=[],u=[],T=[],U=[])}break;case"smoothedLine":if(isNaN(W))z||(this.drawSmoothedGraph(x,u,T,U),x=[],u=[],T=[],U=[]);else{if(Math.abs(E-jb)>=lb||Math.abs(F-kb)>=lb)x.push(E),u.push(F),jb=E,kb=F;ya=E;Ea=F;ka=E;la=F;!Ma||isNaN(N)||isNaN(O)||(T.push(O),U.push(N));void 0==v.lineColor&&void 0==v.fillColors&&isNaN(v.dashLength)||(this.drawSmoothedGraph(x,u,T,U),x=[E],u=[F],T=[],U=[],!Ma||isNaN(N)||isNaN(O)||(T.push(O),U.push(N)),this.lineColorSwitched=v.lineColor,this.fillColorsSwitched=v.fillColors,this.dashLengthSwitched=v.dashLength);v.gap&&(this.drawSmoothedGraph(x,u,T,U),x=[],u=[],T=[],U=[])}break;case"step":if(!isNaN(W)){t?(isNaN(A)||(x.push(A),u.push(F-wa)),u.push(F-wa),x.push(E),u.push(F+Ga),x.push(E),!Ma||isNaN(N)||isNaN(O)||(isNaN(B)||(T.push(B),U.push(N-wa)),T.push(O),U.push(N-wa),T.push(O),U.push(N+Ga))):(isNaN(y)||(u.push(y),x.push(E-wa)),x.push(E-wa),u.push(F),x.push(E+Ga),u.push(F),!Ma||isNaN(N)||isNaN(O)||(isNaN(D)||(T.push(O-wa),U.push(D)),T.push(O-wa),U.push(N),T.push(O+Ga),U.push(N)));A=E;y=F;B=O;D=N;ya=E;Ea=F;ka=E;la=F;if($a||void 0!=v.lineColor||void 0!=v.fillColors||!isNaN(v.dashLength)){var Db=x[x.length-2],dc=u[u.length-2];x.pop();u.pop();T.pop();U.pop();this.drawLineGraph(x,u,T,U);x=[Db];u=[dc];T=[];U=[];Ma&&(T=[Db,Db+wa+Ga],U=[D,D]);t?(u.push(F+Ga),x.push(E)):(x.push(E+Ga),u.push(F));this.lineColorSwitched=v.lineColor;this.fillColorsSwitched=v.fillColors;this.dashLengthSwitched=v.dashLength;m&&(Sa?(this.lineColorSwitched=xa,this.fillColorsSwitched=wb):(this.lineColorSwitched=Ja,this.fillColorsSwitched=Ra))}if(Ob||v.gap)A=y=NaN,this.drawLineGraph(x,u,T,U),x=[],u=[],T=[],U=[]}else if(!z){if(1>=this.periodSpan||1<this.periodSpan&&E-A>wa+Ga)A=y=NaN;this.drawLineGraph(x,u,T,U);x=[];u=[];T=[];U=[]}break;case"column":Ca=Ha;void 0!=v.lineColor&&(Ca=v.lineColor);if(!isNaN(W)){m||(v.isNegative=W<Pa?!0:!1);v.isNegative&&(Ra&&(Na=Ra),void 0!=Ja&&(Ca=Ja));var Qb=f.min,Rb=f.max,ob=ua;isNaN(ob)&&(ob=Pa);if(!(W<Qb&&ob<Qb||W>Rb&&ob>Rb)){var Aa;if(t){"3d"==M?(R=F-(r/2-this.depthCount+1)*(k+V)+V/2+Q*Z,S=O+H*Z,Aa=Z):(R=Math.floor(F-(r/2-Z)*(k+V)+V/2),S=O,Aa=0);K=k;ya=E;Ea=R+k/2;ka=E;la=R+k/2;R+K>q+Aa*Q&&(K=q-R+Aa*Q);R<Aa*Q&&(K+=R,R=Aa*Q);ba=E-O;var ec=S;S=d.fitToBounds(S,0,p);ba+=ec-S;ba=d.fitToBounds(ba,-S,p-S+H*Z);v.labelIsNegative=0>ba?!0:!1;0===ba&&1/W===1/-0&&(v.labelIsNegative=!0);isNaN(G.percentWidthValue)||(K=this.height*G.percentWidthValue/100,R=ja-K/2,Ea=R+K/2);K=d.roundTo(K,2);ba=d.roundTo(ba,2);R<q&&0<K&&(va=new d.Cuboid(h,ba,K,H-a.d3x,Q-a.d3y,Na,Va,da,Ca,X,ga,w,t,ea,bb,mb,aa),v.columnWidth=Math.abs(ba),v.columnHeight=Math.abs(K))}else{"3d"==M?(S=E-(r/2-this.depthCount+1)*(k+V)+V/2+H*Z,R=N+Q*Z,Aa=Z):(S=E-(r/2-Z)*(k+V)+V/2,R=N,Aa=0);K=k;ya=S+k/2;Ea=F;ka=S+k/2;la=F;S+K>p+Aa*H&&(K=p-S+Aa*H);S<Aa*H&&(K+=S-Aa*H,S=Aa*H);ba=F-N;v.labelIsNegative=0<ba?!0:!1;0===ba&&1/W!==1/Math.abs(W)&&(v.labelIsNegative=!0);var fc=R;R=d.fitToBounds(R,this.dy,q);ba+=fc-R;ba=d.fitToBounds(ba,-R+Q*Aa,q-R);isNaN(G.percentWidthValue)||(K=this.width*G.percentWidthValue/100,S=ja-K/2,ya=S+K/2);K=d.roundTo(K,2);ba=d.roundTo(ba,2);S<p+Z*H&&0<K&&(this.showOnAxis&&(R-=Q/2),va=new d.Cuboid(h,K,ba,H-a.d3x,Q-a.d3y,Na,Va,da,Ca,this.lineAlpha,ga,w,t,ea,bb,mb,aa),v.columnHeight=Math.abs(ba),v.columnWidth=Math.abs(K))}}if(va){za=va.set;d.setCN(a,va.set,"graph-"+this.type);d.setCN(a,va.set,"graph-"+this.id);v.className&&d.setCN(a,va.set,v.className,!0);v.columnGraphics=za;S=d.roundTo(S,2);R=d.roundTo(R,2);za.translate(S,R);(v.url||this.showHandOnHover)&&za.setAttr("cursor","pointer");if(!J){"none"==M&&(I=t?(this.end+1-L)*C-c:C*L+c);"3d"==M&&(t?(I=(this.end+1-L)*C-c-1E3*this.depthCount,ya+=H*Z,ka+=H*Z,v.y+=H*Z):(I=(C-c)*(L+1)+1E3*this.depthCount,Ea+=Q*Z,la+=Q*Z,v.y+=Q*Z));if("regular"==M||"100%"==M)I=t?0<Ia.value?(this.end+1-L)*C+c:(this.end+1-L)*C-c:0<Ia.value?C*L+c:C*L-c;this.columnsArray.push({column:va,depth:I});v.x=t?R+K/2:S+K/2;this.ownColumns.push(va);this.animateColumns(va,L,E,O,F,N);this.addListeners(za,v);void 0!==this.tabIndex&&za.setAttr("tabindex",this.tabIndex)}this.columnsSet.push(za)}}break;case"candlestick":if(!isNaN(ua)&&!isNaN(W)){var Xa,cb;Ca=Ha;void 0!=v.lineColor&&(Ca=v.lineColor);ya=E;la=Ea=F;ka=E;if(t){"open"==l&&(ka=O);"high"==l&&(ka=sa);"low"==l&&(ka=qa);E=d.fitToBounds(E,0,pa);O=d.fitToBounds(O,0,pa);qa=d.fitToBounds(qa,0,pa);sa=d.fitToBounds(sa,0,pa);if(0===E&&0===O&&0===qa&&0===sa)continue;if(E==pa&&O==pa&&qa==pa&&sa==pa)continue;R=F-k/2;S=O;K=k;R+K>q&&(K=q-R);0>R&&(K+=R,R=0);if(R<q&&0<K){var Eb,Fb;W>ua?(Eb=[E,sa],Fb=[O,qa]):(Eb=[O,sa],Fb=[E,qa]);!isNaN(sa)&&!isNaN(qa)&&F<q&&0<F&&(Xa=d.line(h,Eb,[F,F],Ca,X,da),cb=d.line(h,Fb,[F,F],Ca,X,da));ba=E-O;va=new d.Cuboid(h,ba,K,H,Q,Na,Ya,da,Ca,X,ga,w,t,ea,bb,mb,aa)}}else{"open"==l&&(la=N);"high"==l&&(la=ta);"low"==l&&(la=ra);F=d.fitToBounds(F,0,Fa);N=d.fitToBounds(N,0,Fa);ra=d.fitToBounds(ra,0,Fa);ta=d.fitToBounds(ta,0,Fa);if(0===F&&0===N&&0===ra&&0===ta)continue;if(F==Fa&&N==Fa&&ra==Fa&&ta==Fa)continue;S=E-k/2;R=N+da/2;K=k;S+K>p&&(K=p-S);0>S&&(K+=S,S=0);ba=F-N;if(S<p&&0<K){Bb&&W>=ua&&(Va=0);var va=new d.Cuboid(h,K,ba,H,Q,Na,Va,da,Ca,X,ga,w,t,ea,bb,mb,aa),Gb,Hb;W>ua?(Gb=[F,ta],Hb=[N,ra]):(Gb=[N,ta],Hb=[F,ra]);!isNaN(ta)&&!isNaN(ra)&&E<p&&0<E&&(Xa=d.line(h,[E,E],Gb,Ca,X,da),cb=d.line(h,[E,E],Hb,Ca,X,da),d.setCN(a,Xa,this.bcn+"line-high"),v.className&&d.setCN(a,Xa,v.className,!0),d.setCN(a,cb,this.bcn+"line-low"),v.className&&d.setCN(a,cb,v.className,!0))}}va&&(za=va.set,v.columnGraphics=za,fa.push(za),za.translate(S,R-da/2),(v.url||this.showHandOnHover)&&za.setAttr("cursor","pointer"),Xa&&(fa.push(Xa),fa.push(cb)),J||(v.x=t?R+K/2:S+K/2,this.animateColumns(va,L,E,O,F,N),this.addListeners(za,v),void 0!==this.tabIndex&&za.setAttr("tabindex",this.tabIndex)))}break;case"ohlc":if(!(isNaN(ua)||isNaN(zb)||isNaN(Ab)||isNaN(W))){var Sb=h.set();fa.push(Sb);W<ua&&(v.isNegative=!0,void 0!=Ja&&(Ha=Ja));void 0!=v.lineColor&&(Ha=v.lineColor);var pb,qb,rb;if(t){la=F;ka=E;"open"==l&&(ka=O);"high"==l&&(ka=sa);"low"==l&&(ka=qa);qa=d.fitToBounds(qa,0,pa);sa=d.fitToBounds(sa,0,pa);if(0===E&&0===O&&0===qa&&0===sa)continue;if(E==pa&&O==pa&&qa==pa&&sa==pa)continue;var Ib=F-k/2,Ib=d.fitToBounds(Ib,0,q),Tb=d.fitToBounds(F,0,q),Jb=F+k/2,Jb=d.fitToBounds(Jb,0,q);0<=O&&O<=pa&&(qb=d.line(h,[O,O],[Ib,Tb],Ha,X,da,ea));0<F&&F<q&&(pb=d.line(h,[qa,sa],[F,F],Ha,X,da,ea));0<=E&&E<=pa&&(rb=d.line(h,[E,E],[Tb,Jb],Ha,X,da,ea))}else{la=F;"open"==l&&(la=N);"high"==l&&(la=ta);"low"==l&&(la=ra);var ka=E,ra=d.fitToBounds(ra,0,Fa),ta=d.fitToBounds(ta,0,Fa),Kb=E-k/2,Kb=d.fitToBounds(Kb,0,p),Ub=d.fitToBounds(E,0,p),Lb=E+k/2,Lb=d.fitToBounds(Lb,0,p);0<=N&&N<=Fa&&(qb=d.line(h,[Kb,Ub],[N,N],Ha,X,da,ea));0<E&&E<p&&(pb=d.line(h,[E,E],[ra,ta],Ha,X,da,ea));0<=F&&F<=Fa&&(rb=d.line(h,[Ub,Lb],[F,F],Ha,X,da,ea))}fa.push(qb);fa.push(pb);fa.push(rb);d.setCN(a,qb,this.bcn+"stroke-open");d.setCN(a,rb,this.bcn+"stroke-close");d.setCN(a,pb,this.bcn+"stroke");v.className&&d.setCN(a,Sb,v.className,!0);ya=E;Ea=F}}if(!J&&!isNaN(W)){var Vb=this.hideBulletsCount;if(this.end-this.start<=Vb||0===Vb){var Wb=this.createBullet(v,ka,la,L),Xb=this.labelText;if(Xb&&!isNaN(ya)&&!isNaN(ya)){var gc=this.createLabel(v,Xb),Yb=0;Wb&&(Yb=Wb.size);this.positionLabel(v,ya,Ea,gc,Yb)}if("regular"==M||"100%"==M){var Zb=f.totalText;if(Zb){var Oa=this.createLabel(v,Zb,f.totalTextColor);d.setCN(a,Oa,this.bcn+"label-total");this.allBullets.push(Oa);if(Oa){var $b=Oa.getBBox(),ac=$b.width,bc=$b.height,db,eb,sb=f.totalTextOffset,cc=f.totals[L];cc&&cc.remove();var fb=0;"column"!=g&&(fb=this.bulletSize);t?(eb=Ea,db=0>W?E-ac/2-2-fb-sb:E+ac/2+3+fb+sb):(db=ya,eb=0>W?F+bc/2+fb+sb:F-bc/2-3-fb-sb);Oa.translate(db,eb);f.totals[L]=Oa;t?(0>eb||eb>q)&&Oa.remove():(0>db||db>p)&&Oa.remove()}}}}}}}this.lastDataItem=v;if("line"==g||"step"==g||"smoothedLine"==g)"smoothedLine"==g?this.drawSmoothedGraph(x,u,T,U):this.drawLineGraph(x,u,T,U),J||this.launchAnimation();this.bulletsHidden&&this.hideBullets();this.customBulletsHidden&&this.hideCustomBullets()},animateColumns:function(a,b){var c=this,e=c.chart.startDuration;0<e&&!c.animationPlayed&&(c.seqAn?(a.set.hide(),c.animationArray.push(a),e=setTimeout(function(){c.animate.call(c)},e/(c.end-c.start+1)*(b-c.start)*1E3),c.timeOuts.push(e)):c.animate(a),c.chart.animatable.push(a))},createLabel:function(a,b,c){var e=this.chart,h=a.labelColor;h||(h=this.color);h||(h=e.color);c&&(h=c);c=this.fontSize;void 0===c&&(this.fontSize=c=e.fontSize);var f=this.labelFunction;b=e.formatString(b,a);b=d.cleanFromEmpty(b);f&&(b=f(a,b));if(void 0!==b&&""!==b)return a=d.text(this.container,b,h,e.fontFamily,c),a.node.style.pointerEvents="none",d.setCN(e,a,this.bcn+"label"),this.bulletSet.push(a),a},positiveClip:function(a){a.clipRect(this.pmx,this.pmy,this.pmw,this.pmh)},negativeClip:function(a){a.clipRect(this.nmx,this.nmy,this.nmw,this.nmh)},drawLineGraph:function(a,b,c,e){var h=this;if(1<a.length){var f=h.noRounding,g=h.set,k=h.chart,l=h.container,m=l.set(),p=l.set();g.push(p);g.push(m);var q=h.lineAlpha,n=h.lineThickness,g=h.fillAlphas,t=h.lineColorR,r=h.negativeLineAlpha;isNaN(r)&&(r=q);var w=h.lineColorSwitched;w&&(t=w);var w=h.fillColorsR,z=h.fillColorsSwitched;z&&(w=z);var x=h.dashLength;(z=h.dashLengthSwitched)&&(x=z);var z=h.negativeLineColor,u=h.negativeFillColors,A=h.negativeFillAlphas,y=h.baseCoord;0!==h.negativeBase&&(y=h.valueAxis.getCoordinate(h.negativeBase,f),y>h.height&&(y=h.height),0>y&&(y=0));q=d.line(l,a,b,t,q,n,x,!1,!0,f);q.node.setAttribute("stroke-linejoin","round");d.setCN(k,q,h.bcn+"stroke");m.push(q);m.click(function(a){h.handleGraphEvent(a,"clickGraph")}).mouseover(function(a){h.handleGraphEvent(a,"rollOverGraph")}).mouseout(function(a){h.handleGraphEvent(a,"rollOutGraph")}).touchmove(function(a){h.chart.handleMouseMove(a)}).touchend(function(a){h.chart.handleTouchEnd(a)});void 0===z||h.useNegativeColorIfDown||(n=d.line(l,a,b,z,r,n,x,!1,!0,f),n.node.setAttribute("stroke-linejoin","round"),d.setCN(k,n,h.bcn+"stroke"),d.setCN(k,n,h.bcn+"stroke-negative"),p.push(n));if(0<g||0<A)if(n=a.join(";").split(";"),r=b.join(";").split(";"),q=k.type,"serial"==q||"radar"==q?0<c.length?(c.reverse(),e.reverse(),n=a.concat(c),r=b.concat(e)):"radar"==q?(r.push(0),n.push(0)):h.rotate?(r.push(r[r.length-1]),n.push(y),r.push(r[0]),n.push(y),r.push(r[0]),n.push(n[0])):(n.push(n[n.length-1]),r.push(y),n.push(n[0]),r.push(y),n.push(a[0]),r.push(r[0])):"xy"==q&&(b=h.fillToAxis)&&(d.isString(b)&&(b=k.getValueAxisById(b)),"H"==b.orientation?(y="top"==b.position?0:b.height,n.push(n[n.length-1]),r.push(y),n.push(n[0]),r.push(y),n.push(a[0]),r.push(r[0])):(y="left"==b.position?0:b.width,r.push(r[r.length-1]),n.push(y),r.push(r[0]),n.push(y),r.push(r[0]),n.push(n[0]))),a=h.gradientRotation,0<g&&(b=d.polygon(l,n,r,w,g,1,"#000",0,a,f),b.pattern(h.pattern,NaN,k.path),d.setCN(k,b,h.bcn+"fill"),m.push(b)),u||void 0!==z)isNaN(A)&&(A=g),u||(u=z),f=d.polygon(l,n,r,u,A,1,"#000",0,a,f),d.setCN(k,f,h.bcn+"fill"),d.setCN(k,f,h.bcn+"fill-negative"),f.pattern(h.pattern,NaN,k.path),p.push(f),p.click(function(a){h.handleGraphEvent(a,"clickGraph")}).mouseover(function(a){h.handleGraphEvent(a,"rollOverGraph")}).mouseout(function(a){h.handleGraphEvent(a,"rollOutGraph")}).touchmove(function(a){h.chart.handleMouseMove(a)}).touchend(function(a){h.chart.handleTouchEnd(a)});h.applyMask(p,m)}},applyMask:function(a,b){var c=a.length();"serial"!=this.chart.type||this.scrollbar||(this.positiveClip(b),0<c&&this.negativeClip(a))},drawSmoothedGraph:function(a,b,c,e){if(1<a.length){var h=this.set,f=this.chart,g=this.container,k=g.set(),l=g.set();h.push(l);h.push(k);var m=this.lineAlpha,p=this.lineThickness,h=this.dashLength,q=this.fillAlphas,n=this.lineColorR,t=this.fillColorsR,r=this.negativeLineColor,w=this.negativeFillColors,z=this.negativeFillAlphas,x=this.baseCoord,u=this.lineColorSwitched;u&&(n=u);(u=this.fillColorsSwitched)&&(t=u);var A=this.negativeLineAlpha;isNaN(A)&&(A=m);u=this.getGradRotation();m=new d.Bezier(g,a,b,n,m,p,t,0,h,void 0,u);d.setCN(f,m,this.bcn+"stroke");k.push(m.path);void 0!==r&&(p=new d.Bezier(g,a,b,r,A,p,t,0,h,void 0,u),d.setCN(f,p,this.bcn+"stroke"),d.setCN(f,p,this.bcn+"stroke-negative"),l.push(p.path));0<q&&(p=a.join(";").split(";"),m=b.join(";").split(";"),n="",0<c.length?(c.push("M"),e.push("M"),c.reverse(),e.reverse(),p=a.concat(c),m=b.concat(e)):(this.rotate?(n+=" L"+x+","+b[b.length-1],n+=" L"+x+","+b[0]):(n+=" L"+a[a.length-1]+","+ -x,n+=" L"+a[0]+","+x),n+=" L"+a[0]+","+b[0]),a=new d.Bezier(g,p,m,NaN,0,0,t,q,h,n,u),d.setCN(f,a,this.bcn+"fill"),a.path.pattern(this.pattern,NaN,f.path),k.push(a.path),w||void 0!==r)&&(z||(z=q),w||(w=r),g=new d.Bezier(g,p,m,NaN,0,0,w,z,h,n,u),g.path.pattern(this.pattern,NaN,f.path),d.setCN(f,g,this.bcn+"fill"),d.setCN(f,g,this.bcn+"fill-negative"),l.push(g.path));this.applyMask(l,k)}},launchAnimation:function(){var a=this,b=a.chart.startDuration;if(0<b&&!a.animationPlayed){var c=a.set,e=a.bulletSet;d.VML||(c.attr({opacity:a.startAlpha}),e.attr({opacity:a.startAlpha}));c.hide();e.hide();a.seqAn?(b=setTimeout(function(){a.animateGraphs.call(a)},a.index*b*1E3),a.timeOuts.push(b)):a.animateGraphs()}},animateGraphs:function(){var a=this.chart,b=this.set,c=this.bulletSet,e=this.x,d=this.y;b.show();c.show();var f=a.startDuration,g=a.startEffect;b&&(this.rotate?(b.translate(-1E3,d),c.translate(-1E3,d)):(b.translate(e,-1E3),c.translate(e,-1E3)),b.animate({opacity:1,translate:e+","+d},f,g),c.animate({opacity:1,translate:e+","+d},f,g),a.animatable.push(b))},animate:function(a){var b=this.chart,c=this.animationArray;!a&&0<c.length&&(a=c[0],c.shift());c=d[d.getEffect(b.startEffect)];b=b.startDuration;a&&(this.rotate?a.animateWidth(b,c):a.animateHeight(b,c),a.set.show())},legendKeyColor:function(){var a=this.legendColor,b=this.lineAlpha;void 0===a&&(a=this.lineColorR,0===b&&(b=this.fillColorsR)&&(a="object"==typeof b?b[0]:b));return a},legendKeyAlpha:function(){var a=this.legendAlpha;void 0===a&&(a=this.lineAlpha,this.fillAlphas>a&&(a=this.fillAlphas),0===a&&(a=this.bulletAlpha),0===a&&(a=1));return a},createBullet:function(a,b,c){if(!isNaN(b)&&!isNaN(c)&&("none"!=this.bullet||this.customBullet||a.bullet||a.customBullet)){var e=this.chart,h=this.container,f=this.bulletOffset,g=this.bulletSize;isNaN(a.bulletSize)||(g=a.bulletSize);var k=a.values.value,l=this.maxValue,m=this.minValue,p=this.maxBulletSize,q=this.minBulletSize;isNaN(l)||(isNaN(k)||(g=(k-m)/(l-m)*(p-q)+q),m==l&&(g=p));l=g;this.bulletAxis&&(g=a.values.error, -isNaN(g)||(k=g),g=this.bulletAxis.stepWidth*k);g<this.minBulletSize&&(g=this.minBulletSize);this.rotate?b=a.isNegative?b-f:b+f:c=a.isNegative?c+f:c-f;q=this.bulletColorR;a.lineColor&&void 0===this.bulletColor&&(this.bulletColorSwitched=a.lineColor);this.bulletColorSwitched&&(q=this.bulletColorSwitched);a.isNegative&&void 0!==this.bulletColorNegative&&(q=this.bulletColorNegative);void 0!==a.color&&(q=a.color);var n;"xy"==e.type&&this.valueField&&(n=this.pattern,a.pattern&&(n=a.pattern));f=this.bullet;a.bullet&&(f=a.bullet);var k=this.bulletBorderThickness,m=this.bulletBorderColorR,p=this.bulletBorderAlpha,t=this.bulletAlpha;m||(m=q);this.useLineColorForBulletBorder&&(m=this.lineColorR,a.isNegative&&this.negativeLineColor&&(m=this.negativeLineColor),this.lineColorSwitched&&(m=this.lineColorSwitched));var r=a.alpha;isNaN(r)||(t=r);n=d.bullet(h,f,g,q,t,k,m,p,l,0,n,e.path);l=this.customBullet;a.customBullet&&(l=a.customBullet);l&&(n&&n.remove(),"function"==typeof l?(l=new l,l.chart=e,a.bulletConfig&&(l.availableSpace=c,l.graph=this,l.graphDataItem=a,l.bulletY=c,a.bulletConfig.minCoord=this.minCoord-c,l.bulletConfig=a.bulletConfig),l.write(h),n&&l.showBullet&&l.set.push(n),a.customBulletGraphics=l.cset,n=l.set):(n=h.set(),l=h.image(l,0,0,g,g),n.push(l),this.centerCustomBullets&&l.translate(-g/2,-g/2)));if(n){(a.url||this.showHandOnHover)&&n.setAttr("cursor","pointer");if("serial"==e.type||"gantt"==e.type)if(-.5>b||b>this.width||c<-g/2||c>this.height)n.remove(),n=null;n&&(this.bulletSet.push(n),n.translate(b,c),this.addListeners(n,a),this.allBullets.push(n));a.bx=b;a.by=c;d.setCN(e,n,this.bcn+"bullet");a.className&&d.setCN(e,n,a.className,!0)}if(n){n.size=g||0;if(e=this.bulletHitAreaSize)h=d.circle(h,e,"#FFFFFF",.001,0),h.translate(b,c),a.hitBullet=h,this.bulletSet.push(h),this.addListeners(h,a);a.bulletGraphics=n;void 0!==this.tabIndex&&n.setAttr("tabindex",this.tabIndex)}else n={size:0};n.graphDataItem=a;return n}},showBullets:function(){var a=this.allBullets,b;this.bulletsHidden=!1;for(b=0;b<a.length;b++)a[b].show()},hideBullets:function(){var a=this.allBullets,b;this.bulletsHidden=!0;for(b=0;b<a.length;b++)a[b].hide()},showCustomBullets:function(){var a=this.allBullets,b;this.customBulletsHidden=!1;for(b=0;b<a.length;b++){var c=a[b].graphDataItem;c&&c.customBulletGraphics&&c.customBulletGraphics.show()}},hideCustomBullets:function(){var a=this.allBullets,b;this.customBulletsHidden=!0;for(b=0;b<a.length;b++){var c=a[b].graphDataItem;c&&c.customBulletGraphics&&c.customBulletGraphics.hide()}},addListeners:function(a,b){var c=this;a.mouseover(function(a){c.handleRollOver(b,a)}).mouseout(function(a){c.handleRollOut(b,a)}).touchend(function(a){c.handleRollOver(b,a);c.chart.panEventsEnabled&&c.handleClick(b,a)}).touchstart(function(a){c.handleRollOver(b,a)}).click(function(a){c.handleClick(b,a)}).dblclick(function(a){c.handleDoubleClick(b,a)}).contextmenu(function(a){c.handleRightClick(b,a)});var e=c.chart;if(e.accessible&&c.accessibleLabel){var d=e.formatString(c.accessibleLabel,b);e.makeAccessible(a,d)}},handleRollOver:function(a,b){this.handleGraphEvent(b,"rollOverGraph");if(a){var c=this.chart;a.bulletConfig&&(c.isRolledOverBullet=!0);var e={type:"rollOverGraphItem",item:a,index:a.index,graph:this,target:this,chart:this.chart,event:b};this.fire(e);c.fire(e);clearTimeout(c.hoverInt);(c=c.chartCursor)&&c.valueBalloonsEnabled||this.showGraphBalloon(a,"V",!0)}},handleRollOut:function(a,b){var c=this.chart;if(a){var e={type:"rollOutGraphItem",item:a,index:a.index,graph:this,target:this,chart:this.chart,event:b};this.fire(e);c.fire(e);c.isRolledOverBullet=!1}this.handleGraphEvent(b,"rollOutGraph");(c=c.chartCursor)&&c.valueBalloonsEnabled||this.hideBalloon()},handleClick:function(a,b){if(!this.chart.checkTouchMoved()&&this.chart.checkTouchDuration(b)){if(a){var c={type:"clickGraphItem",item:a,index:a.index,graph:this,target:this,chart:this.chart,event:b};this.fire(c);this.chart.fire(c);d.getURL(a.url,this.urlTarget)}this.handleGraphEvent(b,"clickGraph")}},handleGraphEvent:function(a,b){var c={type:b,graph:this,target:this,chart:this.chart,event:a};this.fire(c);this.chart.fire(c)},handleRightClick:function(a,b){if(a){var c={type:"rightClickGraphItem",item:a,index:a.index,graph:this,target:this,chart:this.chart,event:b};this.fire(c);this.chart.fire(c)}},handleDoubleClick:function(a,b){if(a){var c={type:"doubleClickGraphItem",item:a,index:a.index,graph:this,target:this,chart:this.chart,event:b};this.fire(c);this.chart.fire(c)}},zoom:function(a,b){this.start=a;this.end=b;this.draw()},changeOpacity:function(a){var b=this.set;b&&b.setAttr("opacity",a);if(b=this.ownColumns){var c;for(c=0;c<b.length;c++){var e=b[c].set;e&&e.setAttr("opacity",a)}}(b=this.bulletSet)&&b.setAttr("opacity",a)},destroy:function(){d.remove(this.set);d.remove(this.bulletSet);var a=this.timeOuts;if(a){var b;for(b=0;b<a.length;b++)clearTimeout(a[b])}this.timeOuts=[]},createBalloon:function(){var a=this.chart;this.balloon?this.balloon.destroy&&this.balloon.destroy():this.balloon={};var b=this.balloon;d.extend(b,a.balloon,!0);b.chart=a;b.mainSet=a.plotBalloonsSet;b.className=this.id},hideBalloon:function(){var a=this,b=a.chart;b.chartCursor?b.chartCursor.valueBalloonsEnabled||b.hideBalloon():b.hideBalloon();clearTimeout(a.hoverInt);a.hoverInt=setTimeout(function(){a.hideBalloonReal.call(a)},b.hideBalloonTime)},hideBalloonReal:function(){this.balloon&&this.balloon.hide();this.fixBulletSize()},fixBulletSize:function(){if(d.isModern){var a=this.resizedDItem;if(a){var b=a.bulletGraphics;if(b&&!b.doNotScale){b.translate(a.bx,a.by,1);var c=this.bulletAlpha;isNaN(a.alpha)||(c=a.alpha);b.setAttr("fill-opacity",c);b.setAttr("stroke-opacity",this.bulletBorderAlpha)}}this.resizedDItem=null}},showGraphBalloon:function(a,b,c,e,h){if(a){var f=this.chart,g=this.balloon,k=0,l=0,m=f.chartCursor,p=!0;m?m.valueBalloonsEnabled||(g=f.balloon,k=this.x,l=this.y,p=!1):(g=f.balloon,k=this.x,l=this.y,p=!1);clearTimeout(this.hoverInt);if(f.chartCursor&&(this.currentDataItem=a,"serial"==f.type&&f.isRolledOverBullet&&f.chartCursor.valueBalloonsEnabled)){this.hideBalloonReal();return}this.resizeBullet(a,e,h);if(g&&g.enabled&&this.showBalloon&&!this.hidden){var m=f.formatString(this.balloonText,a,!0),q=this.balloonFunction;q&&(m=q(a,a.graph));m&&(m=d.cleanFromEmpty(m));m&&""!==m?(e=f.getBalloonColor(this,a),g.drop||(g.pointerOrientation=b),b=a.x,h=a.y,f.rotate&&(b=a.y,h=a.x),b+=k,h+=l,isNaN(b)||isNaN(h)?this.hideBalloonReal():(a=this.width,q=this.height,p&&g.setBounds(k,l,a+k,q+l),g.changeColor(e),g.setPosition(b,h),g.fixPrevious(),g.fixedPosition&&(c=!1),!c&&"radar"!=f.type&&(b<k||b>a+k||h<l-.5||h>q+l)?(g.showBalloon(m),g.hide(0)):(g.followCursor(c),g.showBalloon(m)))):(this.hideBalloonReal(),g.hide(),this.resizeBullet(a,e,h))}else this.hideBalloonReal()}},resizeBullet:function(a,b,c){this.fixBulletSize();if(a&&d.isModern&&(1!=b||!isNaN(c))){var e=a.bulletGraphics;e&&!e.doNotScale&&(e.translate(a.bx,a.by,b),isNaN(c)||(e.setAttr("fill-opacity",c),e.setAttr("stroke-opacity",c)),this.resizedDItem=a)}}})})();(function(){var d=window.AmCharts;d.ChartCursor=d.Class({construct:function(a){this.cname="ChartCursor";this.createEvents("changed","zoomed","onHideCursor","onShowCursor","draw","selected","moved","panning","zoomStarted");this.enabled=!0;this.cursorAlpha=1;this.selectionAlpha=.2;this.cursorColor="#CC0000";this.categoryBalloonAlpha=1;this.color="#FFFFFF";this.type="cursor";this.zoomed=!1;this.zoomable=!0;this.pan=!1;this.categoryBalloonDateFormat="MMM DD, YYYY";this.categoryBalloonText="[[category]]";this.categoryBalloonEnabled=this.valueBalloonsEnabled=!0;this.rolledOver=!1;this.cursorPosition="middle";this.bulletsEnabled=this.skipZoomDispatch=!1;this.bulletSize=8;this.selectWithoutZooming=this.oneBalloonOnly=!1;this.graphBulletSize=1.7;this.animationDuration=.3;this.zooming=!1;this.adjustment=0;this.avoidBalloonOverlapping=!0;this.leaveCursor=!1;this.leaveAfterTouch=!0;this.valueZoomable=!1;this.balloonPointerOrientation="horizontal";this.hLineEnabled=this.vLineEnabled=!0;this.vZoomEnabled=this.hZoomEnabled=!1;d.applyTheme(this,a,this.cname)},draw:function(){this.destroy();var a=this.chart;a.panRequired=!0;var b=a.container;this.rotate=a.rotate;this.container=b;this.prevLineHeight=this.prevLineWidth=NaN;b=b.set();b.translate(this.x,this.y);this.set=b;a.cursorSet.push(b);this.createElements();d.isString(this.limitToGraph)&&(this.limitToGraph=d.getObjById(a.graphs,this.limitToGraph),this.fullWidth=!1,this.cursorPosition="middle");this.pointer=this.balloonPointerOrientation.substr(0,1).toUpperCase();this.isHidden=!1;this.hideLines();this.valueLineAxis||(this.valueLineAxis=a.valueAxes[0])},createElements:function(){var a=this,b=a.chart,c=b.dx,e=b.dy,h=a.width,f=a.height,g,k,l=a.cursorAlpha,m=a.valueLineAlpha;a.rotate?(g=m,k=l):(k=m,g=l);"xy"==b.type&&(k=l,void 0!==m&&(k=m),g=l);a.vvLine=d.line(a.container,[c,0,0],[e,0,f],a.cursorColor,g,1);d.setCN(b,a.vvLine,"cursor-line");d.setCN(b,a.vvLine,"cursor-line-vertical");a.hhLine=d.line(a.container,[0,h,h+c],[0,0,e],a.cursorColor,k,1);d.setCN(b,a.hhLine,"cursor-line");d.setCN(b,a.hhLine,"cursor-line-horizontal");a.vLine=a.rotate?a.vvLine:a.hhLine;a.set.push(a.vvLine);a.set.push(a.hhLine);a.set.node.style.pointerEvents="none";a.fullLines=a.container.set();b=b.cursorLineSet;b.push(a.fullLines);b.translate(a.x,a.y);b.clipRect(-1,-1,h+2,f+2);void 0!==a.tabIndex&&(b.setAttr("tabindex",a.tabIndex),b.keyup(function(b){a.handleKeys(b)}).focus(function(b){a.showCursor()}).blur(function(b){a.hideCursor()}));a.set.clipRect(0,0,h,f)},handleKeys:function(a){var b=this.prevIndex,c=this.chart;if(c){var e=c.chartData;e&&(isNaN(b)&&(b=e.length-1),37!=a.keyCode&&40!=a.keyCode||b--,39!=a.keyCode&&38!=a.keyCode||b++,b=d.fitToBounds(b,c.startIndex,c.endIndex),(a=this.chart.chartData[b])&&this.setPosition(a.x.categoryAxis),this.prevIndex=b)}},update:function(){var a=this.chart;if(a){var b=a.mouseX-this.x,c=a.mouseY-this.y;this.mouseX=b;this.mouseY=c;this.mouse2X=a.mouse2X-this.x;this.mouse2Y=a.mouse2Y-this.y;var e;if(a.chartData&&0<a.chartData.length){this.mouseIsOver()?(this.hideGraphBalloons=!1,this.rolledOver=e=!0,this.updateDrawing(),this.vvLine&&isNaN(this.fx)&&(a.rotate||!this.limitToGraph)&&this.vvLine.translate(b,0),!this.hhLine||!isNaN(this.fy)||a.rotate&&this.limitToGraph||this.hhLine.translate(0,c),isNaN(this.mouse2X)?this.dispatchMovedEvent(b,c):e=!1):this.forceShow||this.hideCursor();if(this.zooming){if(!isNaN(this.mouse2X)){isNaN(this.mouse2X0)||this.dispatchPanEvent();return}if(this.pan){this.dispatchPanEvent();return}(this.hZoomEnabled||this.vZoomEnabled)&&this.zooming&&this.updateSelection()}e&&this.showCursor()}}},updateDrawing:function(){this.drawing&&this.chart.setMouseCursor("crosshair");if(this.drawingNow&&(d.remove(this.drawingLine),1<Math.abs(this.drawStartX-this.mouseX)||1<Math.abs(this.drawStartY-this.mouseY))){var a=this.chart,b=a.marginTop,a=a.marginLeft;this.drawingLine=d.line(this.container,[this.drawStartX+a,this.mouseX+a],[this.drawStartY+b,this.mouseY+b],this.cursorColor,1,1)}},fixWidth:function(a){if(this.fullWidth&&this.prevLineWidth!=a){var b=this.vvLine,c=0;b&&(b.remove(),c=b.x);b=this.container.set();b.translate(c,0);c=d.rect(this.container,a,this.height,this.cursorColor,this.cursorAlpha,this.cursorAlpha,this.cursorColor);d.setCN(this.chart,c,"cursor-fill");c.translate(-a/2-1,0);b.push(c);this.vvLine=b;this.fullLines.push(b);this.prevLineWidth=a}},fixHeight:function(a){if(this.fullWidth&&this.prevLineHeight!=a){var b=this.hhLine,c=0;b&&(b.remove(),c=b.y);b=this.container.set();b.translate(0,c);c=d.rect(this.container,this.width,a,this.cursorColor,this.cursorAlpha);c.translate(0,-a/2);b.push(c);this.fullLines.push(b);this.hhLine=b;this.prevLineHeight=a}},fixVLine:function(a,b){if(!isNaN(a)){if(isNaN(this.prevLineX)){var c=0,e=this.mouseX;if(this.limitToGraph){var d=this.chart.categoryAxis;d&&(this.chart.rotate||(c="bottom"==d.position?this.height:-this.height),e=a)}this.vvLine.translate(e,c)}else this.prevLineX!=a&&this.vvLine.translate(this.prevLineX,this.prevLineY);this.fx=a;this.prevLineX!=a&&(c=this.animationDuration,this.zooming&&(c=0),this.vvLine.stop(),this.vvLine.animate({translate:a+","+b},c,"easeOutSine"),this.prevLineX=a,this.prevLineY=b)}},fixHLine:function(a,b){if(!isNaN(a)){if(isNaN(this.prevLineY)){var c=0,e=this.mouseY;if(this.limitToGraph){var d=this.chart.categoryAxis;d&&(this.chart.rotate&&(c="right"==d.position?this.width:-this.width),e=a)}this.hhLine.translate(c,e)}else this.prevLineY!=a&&this.hhLine.translate(this.prevLineX,this.prevLineY);this.fy=a;this.prevLineY!=a&&(c=this.animationDuration,this.zooming&&(c=0),this.hhLine.stop(),this.hhLine.animate({translate:b+","+a},c,"easeOutSine"),this.prevLineY=a,this.prevLineX=b)}},hideCursor:function(a){this.forceShow=!1;this.chart.wasTouched&&this.leaveAfterTouch||this.isHidden||this.leaveCursor||(this.hideCursorReal(),a?this.chart.handleCursorHide():this.fire({target:this,chart:this.chart,type:"onHideCursor"}),this.chart.setMouseCursor("auto"))},hideCursorReal:function(){this.hideLines();this.isHidden=!0;this.index=this.prevLineY=this.prevLineX=this.mouseY0=this.mouseX0=this.fy=this.fx=NaN},hideLines:function(){this.vvLine&&this.vvLine.hide();this.hhLine&&this.hhLine.hide();this.fullLines&&this.fullLines.hide();this.isHidden=!0;this.chart.handleCursorHide()},showCursor:function(a){!this.drawing&&this.enabled&&(this.vLineEnabled&&this.vvLine&&this.vvLine.show(),this.hLineEnabled&&this.hhLine&&this.hhLine.show(),this.isHidden=!1,this.updateFullLine(),a||this.fire({target:this,chart:this.chart,type:"onShowCursor"}),this.pan&&this.chart.setMouseCursor("move"))},updateFullLine:function(){this.zooming&&this.fullWidth&&this.selection&&(this.rotate?0<this.selection.height&&this.hhLine.hide():0<this.selection.width&&this.vvLine.hide())},updateSelection:function(){if(!this.pan&&this.enabled){var a=this.mouseX,b=this.mouseY;isNaN(this.fx)||(a=this.fx);isNaN(this.fy)||(b=this.fy);this.clearSelection();var c=this.mouseX0,e=this.mouseY0,h=this.width,f=this.height,a=d.fitToBounds(a,0,h),b=d.fitToBounds(b,0,f),g;a<c&&(g=a,a=c,c=g);b<e&&(g=b,b=e,e=g);this.hZoomEnabled?h=a-c:c=0;this.vZoomEnabled?f=b-e:e=0;isNaN(this.mouse2X)&&0<Math.abs(h)&&0<Math.abs(f)&&(a=this.chart,b=d.rect(this.container,h,f,this.cursorColor,this.selectionAlpha),d.setCN(a,b,"cursor-selection"),b.width=h,b.height=f,b.translate(c,e),this.set.push(b),this.selection=b);this.updateFullLine()}},mouseIsOver:function(){var a=this.mouseX,b=this.mouseY;if(this.justReleased)return this.justReleased=!1,!0;if(this.mouseIsDown)return!0;if(!this.chart.mouseIsOver)return this.handleMouseOut(),!1;if(0<a&&a<this.width&&0<b&&b<this.height)return!0;this.handleMouseOut()},fixPosition:function(){this.prevY=this.prevX=NaN},handleMouseDown:function(){this.update();if(this.mouseIsOver())if(this.mouseIsDown=!0,this.mouseX0=this.mouseX,this.mouseY0=this.mouseY,this.mouse2X0=this.mouse2X,this.mouse2Y0=this.mouse2Y,this.drawing)this.drawStartY=this.mouseY,this.drawStartX=this.mouseX,this.drawingNow=!0;else if(this.dispatchMovedEvent(this.mouseX,this.mouseY),!this.pan&&isNaN(this.mouse2X0)&&(isNaN(this.fx)||(this.mouseX0=this.fx),isNaN(this.fy)||(this.mouseY0=this.fy)),this.hZoomEnabled||this.vZoomEnabled){this.zooming=!0;var a={chart:this.chart,target:this,type:"zoomStarted"};a.x=this.mouseX/this.width;a.y=this.mouseY/this.height;this.index0=a.index=this.index;this.timestamp0=this.timestamp;this.fire(a)}},registerInitialMouse:function(){},handleReleaseOutside:function(){this.mouseIsDown=!1;if(this.drawingNow){this.drawingNow=!1;d.remove(this.drawingLine);var a=this.drawStartX,b=this.drawStartY,c=this.mouseX,e=this.mouseY,h=this.chart;(2<Math.abs(a-c)||2<Math.abs(b-e))&&this.fire({type:"draw",target:this,chart:h,initialX:a,initialY:b,finalX:c,finalY:e})}this.zooming&&(this.zooming=!1,this.selectWithoutZooming?this.dispatchZoomEvent("selected"):(this.hZoomEnabled||this.vZoomEnabled)&&this.dispatchZoomEvent("zoomed"),this.rolledOver&&this.dispatchMovedEvent(this.mouseX,this.mouseY));this.mouse2Y0=this.mouse2X0=this.mouseY0=this.mouseX0=NaN},dispatchZoomEvent:function(a){if(!this.pan){var b=this.selection;if(b&&3<Math.abs(b.width)&&3<Math.abs(b.height)){var c=Math.min(this.index,this.index0),e=Math.max(this.index,this.index0),d=c,f=e,g=this.chart,k=g.chartData,l=g.categoryAxis;l&&l.parseDates&&!l.equalSpacing&&(d=k[c]?k[c].time:Math.min(this.timestamp0,this.timestamp),f=k[e]?g.getEndTime(k[e].time):Math.max(this.timestamp0,this.timestamp));var b={type:a,chart:this.chart,target:this,end:f,start:d,startIndex:c,endIndex:e,selectionHeight:b.height,selectionWidth:b.width,selectionY:b.y,selectionX:b.x},m;this.hZoomEnabled&&4<Math.abs(this.mouseX0- -this.mouseX)&&(b.startX=this.mouseX0/this.width,b.endX=this.mouseX/this.width,m=!0);this.vZoomEnabled&&4<Math.abs(this.mouseY0-this.mouseY)&&(b.startY=1-this.mouseY0/this.height,b.endY=1-this.mouseY/this.height,m=!0);m&&(this.prevY=this.prevX=NaN,this.fire(b),"selected"!=a&&this.clearSelection());this.hideCursor()}}},dispatchMovedEvent:function(a,b,c,e){a=Math.round(a);b=Math.round(b);if(!this.isHidden&&(a!=this.prevX||b!=this.prevY||"changed"==c)){c||(c="moved");var d=this.fx,f=this.fy;isNaN(d)&&(d=a);isNaN(f)&&(f=b);var g=!1;this.zooming&&this.pan&&(g=!0);g={hidden:this.isHidden,type:c,chart:this.chart,target:this,x:a,y:b,finalX:d,finalY:f,zooming:this.zooming,panning:g,mostCloseGraph:this.mostCloseGraph,index:this.index,skip:e,hideBalloons:this.hideGraphBalloons};this.prevIndex=this.index;this.rotate?(g.position=b,g.finalPosition=f):(g.position=a,g.finalPosition=d);this.prevX=a;this.prevY=b;e?this.chart.handleCursorMove(g):(this.fire(g),"changed"==c&&this.chart.fire(g))}},dispatchPanEvent:function(){if(this.mouseIsDown){var a=d.roundTo((this.mouseX-this.mouseX0)/this.width,3),b=d.roundTo((this.mouseY-this.mouseY0)/this.height,3),c=d.roundTo((this.mouse2X-this.mouse2X0)/this.width,3),e=d.roundTo((this.mouse2Y-this.mouse2Y0)/this.height,2),h=!1;0!==Math.abs(a)&&0!==Math.abs(b)&&(h=!0);if(this.prevDeltaX==a||this.prevDeltaY==b)h=!1;isNaN(c)||isNaN(e)||(0!==Math.abs(c)&&0!==Math.abs(e)&&(h=!0),this.prevDelta2X!=c&&this.prevDelta2Y!=e)||(h=!1);h&&(this.hideLines(),this.fire({type:"panning",chart:this.chart,target:this,deltaX:a, -deltaY:b,delta2X:c,delta2Y:e,index:this.index}),this.prevDeltaX=a,this.prevDeltaY=b,this.prevDelta2X=c,this.prevDelta2Y=e)}},clearSelection:function(){var a=this.selection;a&&(a.width=0,a.height=0,a.remove())},destroy:function(){this.clear();d.remove(this.selection);this.selection=null;clearTimeout(this.syncTO);d.remove(this.set)},clear:function(){},setTimestamp:function(a){this.timestamp=a},setIndex:function(a,b){a!=this.index&&(this.index=a,b||this.isHidden||this.dispatchMovedEvent(this.mouseX,this.mouseY,"changed"))},handleMouseOut:function(){this.enabled&&this.rolledOver&&(this.leaveCursor||this.setIndex(void 0),this.forceShow=!1,this.hideCursor(),this.rolledOver=!1)},showCursorAt:function(a){var b=this.chart.categoryAxis;b&&this.setPosition(b.categoryToCoordinate(a),a)},setPosition:function(a,b){var c=this.chart,e=c.categoryAxis;if(e){var d,f;void 0===b&&(b=e.coordinateToValue(a));e.showBalloonAt(b,a);this.forceShow=!0;e.stickBalloonToCategory?c.rotate?this.fixHLine(a,0):this.fixVLine(a,0):(this.showCursor(),c.rotate?this.hhLine.translate(0,a):this.vvLine.translate(a,0));c.rotate?d=a:f=a;c.rotate?(this.vvLine&&this.vvLine.hide(),this.hhLine&&this.hhLine.show()):(this.hhLine&&this.hhLine.hide(),this.vvLine&&this.vvLine.show());this.updateFullLine();this.isHidden=!1;this.dispatchMovedEvent(f,d,"moved",!0)}},enableDrawing:function(a){this.enabled=!a;this.hideCursor();this.drawing=a},syncWithCursor:function(a,b){clearTimeout(this.syncTO);a&&(a.isHidden?this.hideCursor(!0):this.syncWithCursorReal(a,b))},isZooming:function(a){this.zooming=a},syncWithCursorReal:function(a,b){var c=a.vvLine,e=a.hhLine;this.index=a.index;this.forceShow=!0;this.zooming&&this.pan||this.showCursor(!0);this.hideGraphBalloons=b;this.justReleased=a.justReleased;this.zooming=a.zooming;this.index0=a.index0;this.mouseX0=a.mouseX0;this.mouseY0=a.mouseY0;this.mouse2X0=a.mouse2X0;this.mouse2Y0=a.mouse2Y0;this.timestamp0=a.timestamp0;this.prevDeltaX=a.prevDeltaX;this.prevDeltaY=a.prevDeltaY;this.prevDelta2X=a.prevDelta2X;this.prevDelta2Y=a.prevDelta2Y;this.fx=a.fx;this.fy=a.fy;a.zooming&&this.updateSelection();var d=a.mouseX,f=a.mouseY;this.rotate?(d=NaN,this.vvLine&&this.vvLine.hide(),this.hhLine&&e&&(isNaN(a.fy)?this.hhLine.translate(0,a.mouseY):this.fixHLine(a.fy,0))):(f=NaN,this.hhLine&&this.hhLine.hide(),this.vvLine&&c&&(isNaN(a.fx)?this.vvLine.translate(a.mouseX,0):this.fixVLine(a.fx,0)));this.dispatchMovedEvent(d,f,"moved",!0)}})})();(function(){var d=window.AmCharts;d.SimpleChartScrollbar=d.Class({construct:function(a){this.createEvents("zoomed","zoomStarted","zoomEnded");this.backgroundColor="#D4D4D4";this.backgroundAlpha=1;this.selectedBackgroundColor="#EFEFEF";this.scrollDuration=this.selectedBackgroundAlpha=1;this.resizeEnabled=!0;this.hideResizeGrips=!1;this.scrollbarHeight=20;this.updateOnReleaseOnly=!1;9>document.documentMode&&(this.updateOnReleaseOnly=!0);this.dragIconHeight=this.dragIconWidth=35;this.dragIcon="dragIconRoundBig";this.dragCursorHover="cursor: move; cursor: grab; cursor: -moz-grab; cursor: -webkit-grab;";this.dragCursorDown="cursor: move; cursor: grab; cursor: -moz-grabbing; cursor: -webkit-grabbing;";this.vResizeCursor="ns-resize";this.hResizeCursor="ew-resize";this.enabled=!0;this.percentStart=this.offset=0;this.percentEnd=1;d.applyTheme(this,a,"SimpleChartScrollbar")},getPercents:function(){var a=this.getDBox(),b=a.x,c=a.y,e=a.width,a=a.height;this.rotate?(b=1-c/this.height,c=1-(c+a)/this.height):(c=b/this.width, -b=(b+e)/this.width);this.percentStart=c;this.percentEnd=b},draw:function(){var a=this;a.destroy();if(a.enabled){var b=a.chart.container,c=a.rotate,e=a.chart;e.panRequired=!0;var h=b.set();a.set=h;c?d.setCN(e,h,"scrollbar-vertical"):d.setCN(e,h,"scrollbar-horizontal");e.scrollbarsSet.push(h);var f,g;c?(f=a.scrollbarHeight,g=e.plotAreaHeight):(g=a.scrollbarHeight,f=e.plotAreaWidth);a.width=f;if((a.height=g)&&f){var k=d.rect(b,f,g,a.backgroundColor,a.backgroundAlpha,1,a.backgroundColor,a.backgroundAlpha); -d.setCN(e,k,"scrollbar-bg");a.bg=k;h.push(k);k=d.rect(b,f,g,"#000",.005);h.push(k);a.invisibleBg=k;k.click(function(){a.handleBgClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()}).touchend(function(){a.handleBgClick()});k=d.rect(b,f,g,a.selectedBackgroundColor,a.selectedBackgroundAlpha);d.setCN(e,k,"scrollbar-bg-selected");a.selectedBG=k;h.push(k);f=d.rect(b,f,g,"#000",.005);a.dragger=f;h.push(f);f.mousedown(function(b){a.handleDragStart(b)}).mouseup(function(){a.handleDragStop()}).mouseover(function(){a.handleDraggerOver()}).mouseout(function(){a.handleMouseOut()}).touchstart(function(b){a.handleDragStart(b)}).touchend(function(){a.handleDragStop()});g=e.pathToImages;var l,k=a.dragIcon.replace(/\.[a-z]*$/i,"");d.isAbsolute(k)&&(g="");c?(l=g+k+"H"+e.extension,g=a.dragIconWidth,c=a.dragIconHeight):(l=g+k+e.extension,c=a.dragIconWidth,g=a.dragIconHeight);k=b.image(l,0,0,c,g);d.setCN(e,k,"scrollbar-grip-left");l=b.image(l,0,0,c,g);d.setCN(e,l,"scrollbar-grip-right");var m=10,p=20;e.panEventsEnabled&&(m=25,p=a.scrollbarHeight);var q=d.rect(b,m,p,"#000",.005),n=d.rect(b,m,p,"#000",.005);n.translate(-(m-c)/2,-(p-g)/2);q.translate(-(m-c)/2,-(p-g)/2); -c=b.set([k,n]);b=b.set([l,q]);a.iconLeft=c;h.push(a.iconLeft);a.iconRight=b;h.push(b);a.updateGripCursor(!1);e.makeAccessible(c,a.accessibleLabel);e.makeAccessible(b,a.accessibleLabel);e.makeAccessible(f,a.accessibleLabel);c.setAttr("role","menuitem");b.setAttr("role","menuitem");f.setAttr("role","menuitem");void 0!==a.tabIndex&&(c.setAttr("tabindex",a.tabIndex),c.keyup(function(b){a.handleKeys(b,1,0)}));void 0!==a.tabIndex&&(f.setAttr("tabindex",a.tabIndex),f.keyup(function(b){a.handleKeys(b,1,1)}));void 0!==a.tabIndex&&(b.setAttr("tabindex",a.tabIndex),b.keyup(function(b){a.handleKeys(b,0,1)}));c.mousedown(function(){a.leftDragStart()}).mouseup(function(){a.leftDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(){a.leftDragStart()}).touchend(function(){a.leftDragStop()});b.mousedown(function(){a.rightDragStart()}).mouseup(function(){a.rightDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(){a.rightDragStart()}).touchend(function(){a.rightDragStop()});d.ifArray(e.chartData)?h.show():h.hide();a.hideDragIcons();a.clipDragger(!1)}h.translate(a.x,a.y);h.node.style.msTouchAction="none";h.node.style.touchAction="none"}},handleKeys:function(a,b,c){this.getPercents();var e=this.percentStart,d=this.percentEnd;if(this.rotate)var f=d,d=e,e=f;if(37==a.keyCode||40==a.keyCode)e-=.02*b,d-=.02*c;if(39==a.keyCode||38==a.keyCode)e+=.02*b,d+=.02*c;this.rotate&&(a=d,d=e,e=a);isNaN(d)||isNaN(e)||this.percentZoom(e,d,!0)},updateScrollbarSize:function(a,b){if(!isNaN(a)&&!isNaN(b)){a=Math.round(a);b=Math.round(b);var c=this.dragger,e,d,f,g,k;this.rotate?(e=0,d=a,f=this.width+1,g=b-a,c.setAttr("height",b-a),c.setAttr("y",d)):(e=a,d=0,f=b-a,g=this.height+1,k=b-a,c.setAttr("x",e),c.setAttr("width",k));this.clipAndUpdate(e,d,f,g)}},update:function(){var a,b=!1,c,e,d=this.x,f=this.y,g=this.dragger,k=this.getDBox();if(k){c=k.x+d;e=k.y+f;var l=k.width,k=k.height,m=this.rotate,p=this.chart,q=this.width,n=this.height,t=p.mouseX,p=p.mouseY;a=this.initialMouse;this.forceClip&&this.clipDragger(!0);if(this.dragging){var r=this.initialCoord;m?(a=r+(p-a),0>a&&(a=0),r=n-k,a>r&&(a=r),g.setAttr("y",a)):(a=r+(t-a),0>a&&(a=0),r=q-l,a>r&&(a=r),g.setAttr("x",a));this.clipDragger(!0)}if(this.resizingRight){if(m)if(a=p-e,!isNaN(this.maxHeight)&&a>this.maxHeight&&(a=this.maxHeight),a+e>n+f&&(a=n-e+f),0>a)this.resizingRight=!1,b=this.resizingLeft=!0;else{if(0===a||isNaN(a))a=.1;g.setAttr("height",a)}else if(a=t-c,!isNaN(this.maxWidth)&&a>this.maxWidth&&(a=this.maxWidth),a+c>q+d&&(a=q-c+d),0>a)this.resizingRight=!1,b=this.resizingLeft=!0;else{if(0===a||isNaN(a))a=.1;g.setAttr("width",a)}this.clipDragger(!0)}if(this.resizingLeft){if(m)if(c=e,e=p,e<f&&(e=f),isNaN(e)&&(e=f),e>n+f&&(e=n+f),a=!0===b?c-e:k+c-e,!isNaN(this.maxHeight)&&a>this.maxHeight&&(a=this.maxHeight,e=c),0>a)this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("y",c+k-f);else{if(0===a||isNaN(a))a=.1;g.setAttr("y",e-f);g.setAttr("height",a)}else if(e=t,e<d&&(e=d),isNaN(e)&&(e=d),e>q+d&&(e=q+d),a=!0===b?c-e:l+c-e,!isNaN(this.maxWidth)&&a>this.maxWidth&&(a=this.maxWidth,e=c),0>a)this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("x",c+l-d);else{if(0===a||isNaN(a))a=.1;g.setAttr("x",e-d);g.setAttr("width",a)}this.clipDragger(!0)}}},stopForceClip:function(){this.animating=this.forceClip=!1},clipDragger:function(a){var b=this.getDBox();if(b){var c=b.x,e=b.y,d=b.width,b=b.height,f=!1;if(this.rotate){if(c=0,d=this.width+1,this.clipY!=e||this.clipH!=b)f=!0}else if(e=0,b=this.height+1,this.clipX!=c||this.clipW!=d)f=!0;f&&(this.clipAndUpdate(c,e,d,b),a&&(this.updateOnReleaseOnly||this.dispatchScrollbarEvent()))}},maskGraphs:function(){},clipAndUpdate:function(a,b,c,d){this.clipX=a;this.clipY=b;this.clipW=c;this.clipH=d;this.selectedBG.setAttr("width",c);this.selectedBG.setAttr("height",d);this.selectedBG.translate(a,b);this.updateDragIconPositions();this.maskGraphs(a,b,c,d)},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart;a.hideBalloon();var b=this.getDBox(),c=b.x,d=b.y,h=b.width,b=b.height;this.getPercents();this.rotate?(c=d,h=this.height/b):h=this.width/h;this.fire({type:"zoomed",position:c,chart:a,target:this,multiplier:h,relativeStart:this.percentStart,relativeEnd:this.percentEnd})}},updateDragIconPositions:function(){var a=this.getDBox(),b=a.x,c=a.y,d=this.iconLeft,h=this.iconRight,f,g,k=this.scrollbarHeight;this.rotate?(f=this.dragIconWidth,g=this.dragIconHeight,d.translate((k-g)/2,c-f/2),h.translate((k-g)/2,c+a.height-f/2)):(f=this.dragIconHeight, -g=this.dragIconWidth,d.translate(b-g/2,(k-f)/2),h.translate(b-g/2+a.width,(k-f)/2))},showDragIcons:function(){this.resizeEnabled&&(this.iconLeft.show(),this.iconRight.show())},hideDragIcons:function(){if(!this.resizingLeft&&!this.resizingRight&&!this.dragging){if(this.hideResizeGrips||!this.resizeEnabled)this.iconLeft.hide(),this.iconRight.hide();this.removeCursors()}},removeCursors:function(){this.chart.setMouseCursor("auto")},fireZoomEvent:function(a){this.fire({type:a,chart:this.chart,target:this})}, -percentZoom:function(a,b,c){a=d.fitToBounds(a,0,b);b=d.fitToBounds(b,a,1);if(this.dragger&&this.enabled){this.dragger.stop();isNaN(a)&&(a=0);isNaN(b)&&(b=1);var e,h;this.rotate?(e=this.height,b=e-e*b,h=e-e*a):(e=this.width,h=e*b,b=e*a);this.updateScrollbarSize(b,h);this.clipDragger(!1);this.getPercents();c&&this.dispatchScrollbarEvent()}},destroy:function(){this.clear();d.remove(this.set);d.remove(this.iconRight);d.remove(this.iconLeft)},clear:function(){},handleDragStart:function(){if(this.enabled){this.fireZoomEvent("zoomStarted");var a=this.chart;this.dragger.stop();this.removeCursors();d.isModern&&(this.dragger.node.style.cssText=this.dragCursorDown);this.dragging=!0;var b=this.getDBox();this.rotate?(this.initialCoord=b.y,this.initialMouse=a.mouseY):(this.initialCoord=b.x,this.initialMouse=a.mouseX)}},handleDragStop:function(){this.updateOnReleaseOnly&&(this.update(),this.skipEvent=!1,this.dispatchScrollbarEvent());this.dragging=!1;this.mouseIsOver&&this.removeCursors();d.isModern&&(this.dragger.node.style.cssText=this.dragCursorHover);this.update();this.fireZoomEvent("zoomEnded")},handleDraggerOver:function(){this.handleMouseOver();d.isModern&&(this.dragger.node.style.cssText=this.dragCursorHover)},leftDragStart:function(){this.fireZoomEvent("zoomStarted");this.dragger.stop();this.resizingLeft=!0;this.updateGripCursor(!0)},updateGripCursor:function(a){d.isModern&&(a=this.rotate?a?this.vResizeCursorDown:this.vResizeCursorHover:a?this.hResizeCursorDown:this.hResizeCursorHover)&&(this.iconRight&&(this.iconRight.node.style.cssText=a),this.iconLeft&&(this.iconLeft.node.style.cssText=a))},leftDragStop:function(){this.resizingLeft&&(this.resizingLeft=!1,this.mouseIsOver||this.removeCursors(),this.updateOnRelease(),this.fireZoomEvent("zoomEnded"));this.updateGripCursor(!1)},rightDragStart:function(){this.fireZoomEvent("zoomStarted");this.dragger.stop();this.resizingRight=!0;this.updateGripCursor(!0)},rightDragStop:function(){this.resizingRight&&(this.resizingRight=!1,this.mouseIsOver||this.removeCursors(),this.updateOnRelease(),this.fireZoomEvent("zoomEnded"));this.updateGripCursor(!1)},iconRollOut:function(){this.removeCursors()},iconRollOver:function(){this.rotate?this.vResizeCursor&&this.chart.setMouseCursor(this.vResizeCursor):this.hResizeCursor&&this.chart.setMouseCursor(this.hResizeCursor);this.handleMouseOver()},getDBox:function(){if(this.dragger)return this.dragger.getBBox()},handleBgClick:function(){var a=this;if(!a.resizingRight&&!a.resizingLeft){a.zooming=!0;var b,c,e=a.scrollDuration,h=a.dragger;b=a.getDBox();var f=b.height,g=b.width;c=a.chart;var k=a.y,l=a.x,m=a.rotate;m?(b="y",c=c.mouseY-f/2-k,c=d.fitToBounds(c,0,a.height-f)):(b="x",c=c.mouseX-g/2-l,c=d.fitToBounds(c,0,a.width-g));a.updateOnReleaseOnly?(a.skipEvent=!1,h.setAttr(b,c),a.dispatchScrollbarEvent(),a.clipDragger()):(a.animating=!0,c=Math.round(c),m?h.animate({y:c},e,">"):h.animate({x:c},e,">"),a.forceClip=!0,clearTimeout(a.forceTO),a.forceTO=setTimeout(function(){a.stopForceClip.call(a)},5E3*e))}},updateOnRelease:function(){this.updateOnReleaseOnly&&(this.update(),this.skipEvent=!1,this.dispatchScrollbarEvent())},handleReleaseOutside:function(){if(this.set){if(this.resizingLeft||this.resizingRight||this.dragging)this.dragging=this.resizingRight=this.resizingLeft=!1,this.updateOnRelease(),this.removeCursors();this.animating=this.mouseIsOver=!1;this.hideDragIcons();this.update()}},handleMouseOver:function(){this.mouseIsOver=!0;this.showDragIcons()},handleMouseOut:function(){this.mouseIsOver=!1;this.hideDragIcons();this.removeCursors()}})})();(function(){var d=window.AmCharts;d.ChartScrollbar=d.Class({inherits:d.SimpleChartScrollbar,construct:function(a){this.cname="ChartScrollbar";d.ChartScrollbar.base.construct.call(this,a);this.graphLineColor="#BBBBBB";this.graphLineAlpha=0;this.graphFillColor="#BBBBBB";this.graphFillAlpha=1;this.selectedGraphLineColor="#888888";this.selectedGraphLineAlpha=0;this.selectedGraphFillColor="#888888";this.selectedGraphFillAlpha=1;this.gridCount=0;this.gridColor="#FFFFFF";this.gridAlpha=.7;this.skipEvent=this.autoGridCount=!1;this.color="#FFFFFF";this.scrollbarCreated=!1;this.oppositeAxis=!0;this.accessibleLabel="Zoom chart using cursor arrows";d.applyTheme(this,a,this.cname)},init:function(){var a=this.categoryAxis,b=this.chart,c=this.gridAxis;a||("CategoryAxis"==this.gridAxis.cname?(this.catScrollbar=!0,a=new d.CategoryAxis,a.id="scrollbar"):(a=new d.ValueAxis,a.data=b.chartData,a.id=c.id,a.type=c.type,a.maximumDate=c.maximumDate,a.minimumDate=c.minimumDate,a.minPeriod=c.minPeriod,a.minMaxField=c.minMaxField),this.categoryAxis=a);a.chart=b;var e=b.categoryAxis;e&&(a.firstDayOfWeek=e.firstDayOfWeek);a.dateFormats=c.dateFormats;a.markPeriodChange=c.markPeriodChange;a.boldPeriodBeginning=c.boldPeriodBeginning;a.labelFunction=c.labelFunction;a.axisItemRenderer=d.RecItem;a.axisRenderer=d.RecAxis;a.guideFillRenderer=d.RecFill;a.inside=!0;a.fontSize=this.fontSize;a.tickLength=0;a.axisAlpha=0;d.isString(this.graph)&&(this.graph=d.getObjById(b.graphs,this.graph));(a=this.graph)&&this.catScrollbar&&(c=this.valueAxis,c||(this.valueAxis=c=new d.ValueAxis,c.visible=!1,c.scrollbar=!0,c.axisItemRenderer=d.RecItem,c.axisRenderer=d.RecAxis,c.guideFillRenderer=d.RecFill,c.labelsEnabled=!1,c.chart=b),b=this.unselectedGraph,b||(b=new d.AmGraph,b.scrollbar=!0,this.unselectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers),b=this.selectedGraph,b||(b=new d.AmGraph,b.scrollbar=!0,this.selectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers));this.scrollbarCreated=!0},draw:function(){var a=this;d.ChartScrollbar.base.draw.call(a);if(a.enabled){a.scrollbarCreated||a.init();var b=a.chart,c=b.chartData,e=a.categoryAxis,h=a.rotate,f=a.x,g=a.y,k=a.width,l=a.height,m=a.gridAxis,p=a.set;e.setOrientation(!h);e.parseDates=m.parseDates;"ValueAxis"==a.categoryAxis.cname&&(e.rotate=!h);e.equalSpacing=m.equalSpacing;e.minPeriod=m.minPeriod;e.startOnAxis=m.startOnAxis;e.width=k-1;e.height=l;e.gridCount=a.gridCount;e.gridColor=a.gridColor;e.gridAlpha=a.gridAlpha;e.color=a.color;e.tickLength=0;e.axisAlpha=0;e.autoGridCount=a.autoGridCount;e.parseDates&&!e.equalSpacing&&e.timeZoom(b.firstTime,b.lastTime);e.minimum=a.gridAxis.fullMin;e.maximum=a.gridAxis.fullMax;e.strictMinMax=!0;e.zoom(0,c.length-1);if((m=a.graph)&&a.catScrollbar){var q=a.valueAxis,n=m.valueAxis;q.id=n.id;q.rotate=h;q.setOrientation(h);q.width=k;q.height=l;q.dataProvider=c;q.reversed=n.reversed;q.logarithmic=n.logarithmic;q.gridAlpha=0;q.axisAlpha=0;p.push(q.set);h?(q.y=g,q.x=0):(q.x=f,q.y=0);var f=Infinity,g=-Infinity,t;for(t=0;t<c.length;t++){var r=c[t].axes[n.id].graphs[m.id].values,w;for(w in r)if(r.hasOwnProperty(w)&&"percents"!=w&&"total"!=w){var z=r[w];z<f&&(f=z);z>g&&(g=z)}}Infinity!=f&&(q.minimum=f);-Infinity!=g&&(q.maximum=g+.1*(g-f));f==g&&(--q.minimum,q.maximum+=1);void 0!==a.minimum&&(q.minimum=a.minimum);void 0!==a.maximum&&(q.maximum=a.maximum);q.zoom(0,c.length-1);w=a.unselectedGraph;w.id=m.id;w.bcn="scrollbar-graph-";w.rotate=h;w.chart=b;w.data=c;w.valueAxis=q;w.chart=m.chart;w.categoryAxis=a.categoryAxis;w.periodSpan=m.periodSpan;w.valueField=m.valueField;w.openField=m.openField;w.closeField=m.closeField;w.highField=m.highField;w.lowField=m.lowField;w.lineAlpha=a.graphLineAlpha;w.lineColorR=a.graphLineColor;w.fillAlphas=a.graphFillAlpha;w.fillColorsR=a.graphFillColor;w.connect=m.connect;w.hidden=m.hidden;w.width=k;w.height=l;w.pointPosition=m.pointPosition;w.stepDirection=m.stepDirection;w.periodSpan=m.periodSpan;n=a.selectedGraph;n.id=m.id;n.bcn=w.bcn+"selected-";n.rotate=h;n.chart=b;n.data=c;n.valueAxis=q;n.chart=m.chart;n.categoryAxis=e;n.periodSpan=m.periodSpan;n.valueField=m.valueField;n.openField=m.openField;n.closeField=m.closeField;n.highField=m.highField;n.lowField=m.lowField;n.lineAlpha=a.selectedGraphLineAlpha;n.lineColorR=a.selectedGraphLineColor;n.fillAlphas=a.selectedGraphFillAlpha;n.fillColorsR=a.selectedGraphFillColor;n.connect=m.connect;n.hidden=m.hidden;n.width=k;n.height=l;n.pointPosition=m.pointPosition;n.stepDirection=m.stepDirection;n.periodSpan=m.periodSpan;b=a.graphType;b||(b=m.type);w.type=b;n.type=b;c=c.length-1;w.zoom(0,c);n.zoom(0,c);n.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});w.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});p.push(w.set);p.push(n.set)}p.push(e.set);p.push(e.labelsSet);a.bg.toBack();a.invisibleBg.toFront();a.dragger.toFront();a.iconLeft.toFront();a.iconRight.toFront()}},timeZoom:function(a,b,c){this.startTime=a;this.endTime=b;this.timeDifference=b-a;this.skipEvent=!d.toBoolean(c);this.zoomScrollbar();this.dispatchScrollbarEvent()},zoom:function(a,b){this.start=a;this.end=b;this.skipEvent=!0;this.zoomScrollbar()},dispatchScrollbarEvent:function(){if(this.categoryAxis&&"ValueAxis"==this.categoryAxis.cname)d.ChartScrollbar.base.dispatchScrollbarEvent.call(this);else if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart.chartData,b,c,e=this.dragger.getBBox();b=e.x;var h=e.y,f=e.width,e=e.height,g=this.chart;this.rotate?(b=h,c=e):c=f;f={type:"zoomed",target:this};f.chart=g;var k=this.categoryAxis,l=this.stepWidth,h=g.minSelectedTime,e=g.maxSelectedTime,m=!1;if(k.parseDates&&!k.equalSpacing){if(a=g.lastTime,g=g.firstTime,k=Math.round(b/l)+g,b=this.dragging?k+this.timeDifference:Math.round((b+c)/l)+g,k>b&&(k=b),0<h&&b-k<h&&(b=Math.round(k+(b-k)/2),m=Math.round(h/2),k=b-m,b+=m,m=!0),0<e&&b-k>e&&(b=Math.round(k+(b-k)/2),m=Math.round(e/2),k=b-m,b+=m,m=!0),b>a&&(b= -a),b-h<k&&(k=b-h),k<g&&(k=g),k+h>b&&(b=k+h),k!=this.startTime||b!=this.endTime)this.startTime=k,this.endTime=b,f.start=k,f.end=b,f.startDate=new Date(k),f.endDate=new Date(b),this.fire(f)}else{k.startOnAxis||(b+=l/2);c-=this.stepWidth/2;h=k.xToIndex(b);b=k.xToIndex(b+c);if(h!=this.start||this.end!=b)k.startOnAxis&&(this.resizingRight&&h==b&&b++,this.resizingLeft&&h==b&&(0<h?h--:b=1)),this.start=h,this.end=this.dragging?this.start+this.difference:b,f.start=this.start,f.end=this.end,k.parseDates&&(a[this.start]&&(f.startDate=new Date(a[this.start].time)),a[this.end]&&(f.endDate=new Date(a[this.end].time))),this.fire(f);this.percentStart=h;this.percentEnd=b}m&&this.zoomScrollbar(!0)}},zoomScrollbar:function(a){if((!(this.dragging||this.resizingLeft||this.resizingRight||this.animating)||a)&&this.dragger&&this.enabled){var b,c,d=this.chart;a=d.chartData;var h=this.categoryAxis;h.parseDates&&!h.equalSpacing?(a=h.stepWidth,c=d.firstTime,b=a*(this.startTime-c),c=a*(this.endTime-c)):(a[this.start]&&(b=a[this.start].x[h.id]),a[this.end]&&(c=a[this.end].x[h.id]),a=h.stepWidth,h.startOnAxis||(d=a/2,b-=d,c+=d));this.stepWidth=a;isNaN(b)||isNaN(c)||this.updateScrollbarSize(b,c)}},maskGraphs:function(a,b,c,d){var h=this.selectedGraph;h&&h.set.clipRect(a,b,c,d)},handleDragStart:function(){d.ChartScrollbar.base.handleDragStart.call(this);this.difference=this.end-this.start;this.timeDifference=this.endTime-this.startTime;0>this.timeDifference&&(this.timeDifference=0)},handleBackgroundClick:function(){d.ChartScrollbar.base.handleBackgroundClick.call(this);this.dragging||(this.difference=this.end-this.start,this.timeDifference=this.endTime-this.startTime,0>this.timeDifference&&(this.timeDifference=0))}})})();(function(){var d=window.AmCharts;d.AmBalloon=d.Class({construct:function(a){this.cname="AmBalloon";this.enabled=!0;this.fillColor="#FFFFFF";this.fillAlpha=.8;this.borderThickness=2;this.borderColor="#FFFFFF";this.borderAlpha=1;this.cornerRadius=0;this.maxWidth=220;this.horizontalPadding=8;this.verticalPadding=4;this.pointerWidth=6;this.pointerOrientation="V";this.color="#000000";this.adjustBorderColor=!0;this.show=this.follow=this.showBullet=!1;this.bulletSize=3;this.shadowAlpha=.4;this.shadowColor="#000000";this.fadeOutDuration=this.animationDuration=.3;this.fixedPosition=!0;this.offsetY=6;this.offsetX=1;this.textAlign="center";this.disableMouseEvents=!0;this.deltaSignX=this.deltaSignY=1;d.isModern||(this.offsetY*=1.5);this.sdy=this.sdx=0;d.applyTheme(this,a,this.cname)},draw:function(){var a=this.pointToX,b=this.pointToY;d.isModern||(this.drop=!1);var c=this.chart;d.VML&&(this.fadeOutDuration=0);this.xAnim&&c.stopAnim(this.xAnim);this.yAnim&&c.stopAnim(this.yAnim);this.sdy=this.sdx=0;if(!isNaN(a)){var e=this.follow,h=c.container,f=this.set;d.remove(f);this.removeDiv();f=h.set();f.node.style.pointerEvents="none";this.set=f;this.mainSet?(this.mainSet.push(this.set),this.sdx=this.mainSet.x,this.sdy=this.mainSet.y):c.balloonsSet.push(f);if(this.show){var g=this.l,k=this.t,l=this.r,m=this.b,p=this.balloonColor,q=this.fillColor,n=this.borderColor,t=q;void 0!=p&&(this.adjustBorderColor?t=n=p:q=p);var r=this.horizontalPadding,w=this.verticalPadding,z=this.pointerWidth,x=this.pointerOrientation,u=this.cornerRadius,A=c.fontFamily,y=this.fontSize;void 0==y&&(y=c.fontSize);var p=document.createElement("div"),B=c.classNamePrefix;p.className=B+"-balloon-div";this.className&&(p.className=p.className+" "+B+"-balloon-div-"+this.className);B=p.style;this.disableMouseEvents&&(B.pointerEvents="none");B.position="absolute";var D=this.minWidth,C=document.createElement("div");p.appendChild(C);var I=C.style;isNaN(D)||(I.minWidth=D-2*r+"px");I.textAlign=this.textAlign;I.maxWidth=this.maxWidth+"px";I.fontSize=y+"px";I.color=this.color;I.fontFamily=A;C.innerHTML=this.text;c.chartDiv.appendChild(p);this.textDiv=p;var I=p.offsetWidth,H=p.offsetHeight;p.clientHeight&&(I=p.clientWidth,H=p.clientHeight);A=H+2*w;C=I+2*r;!isNaN(D)&&C<D&&(C=D);window.opera&&(A+=2);var Q=!1,y=this.offsetY;c.handDrawn&&(y+=c.handDrawScatter+2);"H"!=x?(D=a-C/2,b<k+A+10&&"down"!=x?(Q=!0,e&&(b+=y),y=b+z,this.deltaSignY=-1):(e&&(b-=y),y=b-A-z,this.deltaSignY=1)):(2*z>A&&(z=A/2),y=b-A/2,a<g+(l-g)/2?(D=a+z,this.deltaSignX=-1):(D=a-C-z,this.deltaSignX= -1));y+A>=m&&(y=m-A);y<k&&(y=k);D<g&&(D=g);D+C>l&&(D=l-C);var k=y+w,m=D+r,M=this.shadowAlpha,P=this.shadowColor,r=this.borderThickness,ia=this.bulletSize,J,w=this.fillAlpha,aa=this.borderAlpha;this.showBullet&&(J=d.circle(h,ia,t,w),f.push(J));this.drop?(g=C/1.6,l=0,"V"==x&&(x="down"),"H"==x&&(x="left"),"down"==x&&(D=a+1,y=b-g-g/3),"up"==x&&(l=180,D=a+1,y=b+g+g/3),"left"==x&&(l=270,D=a+g+g/3+2,y=b),"right"==x&&(l=90,D=a-g-g/3+2,y=b),k=y-H/2+1,m=D-I/2-1,q=d.drop(h,g,l,q,w,r,n,aa)):0<u||0===z?(0<M&&(a=d.rect(h,C,A,q,0,r+1,P,M,u),d.isModern?a.translate(1,1):a.translate(4,4),f.push(a)),q=d.rect(h,C,A,q,w,r,n,aa,u)):(t=[],u=[],"H"!=x?(g=a-D,g>C-z&&(g=C-z),g<z&&(g=z),t=[0,g-z,a-D,g+z,C,C,0,0],u=Q?[0,0,b-y,0,0,A,A,0]:[A,A,b-y,A,A,0,0,A]):(x=b-y,x>A-z&&(x=A-z),x<z&&(x=z),u=[0,x-z,b-y,x+z,A,A,0,0],t=a<g+(l-g)/2?[0,0,D<a?0:a-D,0,0,C,C,0]:[C,C,D+C>a?C:a-D,C,C,0,0,C]),0<M&&(a=d.polygon(h,t,u,q,0,r,P,M),a.translate(1,1),f.push(a)),q=d.polygon(h,t,u,q,w,r,n,aa));this.bg=q;f.push(q);q.toFront();d.setCN(c,q, -"balloon-bg");this.className&&d.setCN(c,q,"balloon-bg-"+this.className);h=1*this.deltaSignX;m+=this.sdx;k+=this.sdy;B.left=m+"px";B.top=k+"px";f.translate(D-h,y,1,!0);q=q.getBBox();this.bottom=y+A+1;this.yPos=q.y+y;J&&J.translate(this.pointToX-D+h,b-y);b=this.animationDuration;0<this.animationDuration&&!e&&!isNaN(this.prevX)&&(f.translate(this.prevX,this.prevY,NaN,!0),f.animate({translate:D-h+","+y},b,"easeOutSine"),p&&(B.left=this.prevTX+"px",B.top=this.prevTY+"px",this.xAnim=c.animate({node:p},"left",this.prevTX,m,b,"easeOutSine","px"),this.yAnim=c.animate({node:p},"top",this.prevTY,k,b,"easeOutSine","px")));this.prevX=D-h;this.prevY=y;this.prevTX=m;this.prevTY=k}}},fixPrevious:function(){this.rPrevX=this.prevX;this.rPrevY=this.prevY;this.rPrevTX=this.prevTX;this.rPrevTY=this.prevTY},restorePrevious:function(){this.prevX=this.rPrevX;this.prevY=this.rPrevY;this.prevTX=this.rPrevTX;this.prevTY=this.rPrevTY},followMouse:function(){if(this.follow&&this.show){var a=this.chart.mouseX-this.offsetX*this.deltaSignX-this.sdx,b=this.chart.mouseY-this.sdy;this.pointToX=a;this.pointToY=b;if(a!=this.previousX||b!=this.previousY)if(this.previousX=a,this.previousY=b,0===this.cornerRadius)this.draw();else{var c=this.set;if(c){var d=c.getBBox(),a=a-d.width/2,h=b-d.height-10;a<this.l&&(a=this.l);a>this.r-d.width&&(a=this.r-d.width);h<this.t&&(h=b+10);c.translate(a,h);b=this.textDiv.style;b.left=a+this.horizontalPadding+"px";b.top=h+this.verticalPadding+"px"}}}},changeColor:function(a){this.balloonColor=a},setBounds:function(a,b,c,d){this.l=a;this.t=b;this.r=c;this.b=d;this.destroyTO&&clearTimeout(this.destroyTO)},showBalloon:function(a){if(this.text!=a||this.positionChanged)this.text=a,this.isHiding=!1,this.show=!0,this.destroyTO&&clearTimeout(this.destroyTO),a=this.chart,this.fadeAnim1&&a.stopAnim(this.fadeAnim1),this.fadeAnim2&&a.stopAnim(this.fadeAnim2),this.draw(),this.positionChanged=!1},hide:function(a){var b=this;b.text=void 0;isNaN(a)&&(a=b.fadeOutDuration);var c=b.chart;if(0<a&&!b.isHiding){b.isHiding=!0;b.destroyTO&&clearTimeout(b.destroyTO);b.destroyTO=setTimeout(function(){b.destroy.call(b)},1E3*a);b.follow=!1;b.show=!1;var d=b.set;d&&(d.setAttr("opacity",b.fillAlpha),b.fadeAnim1=d.animate({opacity:0},a,"easeInSine"));b.textDiv&&(b.fadeAnim2=c.animate({node:b.textDiv},"opacity",1,0,a,"easeInSine",""))}else b.show=!1,b.follow=!1,b.destroy()},setPosition:function(a,b){if(a!=this.pointToX||b!=this.pointToY)this.previousX=this.pointToX,this.previousY=this.pointToY,this.pointToX=a,this.pointToY=b,this.positionChanged=!0},followCursor:function(a){var b=this;b.follow=a;clearInterval(b.interval);var c=b.chart.mouseX-b.sdx,d=b.chart.mouseY-b.sdy;!isNaN(c)&&a&&(b.pointToX=c-b.offsetX*b.deltaSignX,b.pointToY=d,b.followMouse(),b.interval=setInterval(function(){b.followMouse.call(b)},40))},removeDiv:function(){if(this.textDiv){var a=this.textDiv.parentNode;a&&a.removeChild(this.textDiv)}},destroy:function(){clearInterval(this.interval);d.remove(this.set);this.removeDiv();this.set=null}})})();(function(){var d=window.AmCharts;d.AmCoordinateChart=d.Class({inherits:d.AmChart,construct:function(a){d.AmCoordinateChart.base.construct.call(this,a);this.theme=a;this.createEvents("rollOverGraphItem","rollOutGraphItem","clickGraphItem","doubleClickGraphItem","rightClickGraphItem","clickGraph","rollOverGraph","rollOutGraph");this.startAlpha=1;this.startDuration=0;this.startEffect="elastic";this.sequencedAnimation=!0;this.colors="#FF6600 #FCD202 #B0DE09 #0D8ECF #2A0CD0 #CD0D74 #CC0000 #00CC00 #0000CC #DDDDDD #999999 #333333 #990000".split(" ");this.balloonDateFormat="MMM DD, YYYY";this.valueAxes=[];this.graphs=[];this.guides=[];this.gridAboveGraphs=!1;d.applyTheme(this,a,"AmCoordinateChart")},initChart:function(){d.AmCoordinateChart.base.initChart.call(this);this.drawGraphs=!0;var a=this.categoryAxis;a&&(this.categoryAxis=d.processObject(a,d.CategoryAxis,this.theme));this.processValueAxes();this.createValueAxes();this.processGraphs();this.processGuides();d.VML&&(this.startAlpha=1);this.setLegendData(this.graphs);this.gridAboveGraphs&&(this.gridSet.toFront(),this.bulletSet.toFront(),this.balloonsSet.toFront())},createValueAxes:function(){if(0===this.valueAxes.length){var a=new d.ValueAxis;this.addValueAxis(a)}},parseData:function(){this.processValueAxes();this.processGraphs()},parseSerialData:function(a){this.chartData=[];if(a)if(0<this.processTimeout){1>this.processCount&&(this.processCount=1);var b=a.length/this.processCount;this.parseCount=Math.ceil(b)-1;for(var c=0;c<b;c++)this.delayParseSerialData(a,c)}else this.parseCount=0,this.parsePartSerialData(a,0,a.length,0);else this.onDataUpdated()},delayParseSerialData:function(a,b){var c=this,d=c.processCount;setTimeout(function(){c.parsePartSerialData.call(c,a,b*d,(b+1)*d,b)},c.processTimeout)},parsePartSerialData:function(a,b,c,e){c>a.length&&(c=a.length);var h=this.graphs,f={},g=this.seriesIdField;g||(g=this.categoryField);var k=!1,l,m=this.categoryAxis,p,q,n;m&&(k=m.parseDates,p=m.forceShowField,n=m.classNameField,q=m.labelColorField,l=m.categoryFunction);var t,r,w={},z;k&&(t=d.extractPeriod(m.minPeriod),r=t.period,t=t.count,z=d.getPeriodDuration(r,t));var x={};this.lookupTable=x;var u,A=this.dataDateFormat,y={};for(u=b;u<c;u++){var B={},D=a[u];b=D[this.categoryField];B.dataContext=D;B.category=l?l(b,D,m):String(b);p&&(B.forceShow=D[p]);n&&(B.className=D[n]);q&&(B.labelColor=D[q]);x[D[g]]=B;if(k&&(m.categoryFunction?b=m.categoryFunction(b,D,m):(!A||b instanceof Date||(b=b.toString()+" |"),b=d.getDate(b,A,m.minPeriod)),b=d.resetDateToMin(b,r,t,m.firstDayOfWeek),B.category=b,B.time=b.getTime(),isNaN(B.time)))continue;var C=this.valueAxes;B.axes={};B.x={};var I;for(I=0;I<C.length;I++){var H=C[I].id;B.axes[H]={};B.axes[H].graphs={};var Q;for(Q=0;Q<h.length;Q++){b=h[Q];var M=b.id,P=1.1;isNaN(b.gapPeriod)||(P=b.gapPeriod);var ia=b.periodValue;if(b.valueAxis.id==H){B.axes[H].graphs[M]={};var J={};J.index=u;var aa=D;b.dataProvider&&(aa=f);J.values=this.processValues(aa,b,ia);if(!b.connect||b.forceGap&&!isNaN(b.gapPeriod))if(y&&y[M]&&0<P&&B.time-w[M]>=z*P&&(y[M].gap=!0),b.forceGap){var P=0,ma;for(ma in J.values)P++;0<P&&(w[M]=B.time,y[M]=J)}else w[M]=B.time,y[M]=J;this.processFields(b,J,aa);J.category=B.category;J.serialDataItem=B;J.graph=b;B.axes[H].graphs[M]=J}}}this.chartData[u]=B}if(this.parseCount==e){for(a=0;a<h.length;a++)b=h[a],b.dataProvider&&this.parseGraphData(b);this.dataChanged=!1;this.dispatchDataUpdated=!0;this.onDataUpdated()}},processValues:function(a,b,c){var e={},h,f=!1;"candlestick"!=b.type&&"ohlc"!=b.type||""===c||(f=!0);for(var g="value error open close low high".split(" "),k=0;k<g.length;k++){var l=g[k];"value"!=l&&"error"!=l&&f&&(c=l.charAt(0).toUpperCase()+l.slice(1));var m=a[b[l+"Field"]+c];null!==m&&(h=Number(m),isNaN(h)||(e[l]=h),"date"==b.valueAxis.type&&void 0!==m&&(h=d.getDate(m,b.chart.dataDateFormat),e[l]=h.getTime()))}return e},parseGraphData:function(a){var b=a.dataProvider,c=a.seriesIdField;c||(c=this.seriesIdField);c||(c=this.categoryField);var d;for(d=0;d<b.length;d++){var h=b[d],f=this.lookupTable[String(h[c])],g=a.valueAxis.id;f&&(g=f.axes[g].graphs[a.id],g.serialDataItem=f,g.values=this.processValues(h,a,a.periodValue),this.processFields(a,g,h))}},addValueAxis:function(a){a.chart=this;this.valueAxes.push(a);this.validateData()},removeValueAxesAndGraphs:function(){var a=this.valueAxes,b;for(b=a.length-1;-1<b;b--)this.removeValueAxis(a[b])},removeValueAxis:function(a){var b=this.graphs,c;for(c=b.length-1;0<=c;c--){var d=b[c];d&&d.valueAxis==a&&this.removeGraph(d)}b=this.valueAxes;for(c=b.length-1;0<=c;c--)b[c]==a&&b.splice(c,1);this.validateData()},addGraph:function(a){this.graphs.push(a);this.chooseGraphColor(a,this.graphs.length-1);this.validateData()},removeGraph:function(a){var b=this.graphs,c;for(c=b.length-1;0<=c;c--)b[c]==a&&(b.splice(c,1),a.destroy());this.validateData()},handleValueAxisZoom:function(){},processValueAxes:function(){var a=this.valueAxes,b;for(b=0;b<a.length;b++){var c=a[b],c=d.processObject(c,d.ValueAxis,this.theme);a[b]=c;c.chart=this;c.init();this.listenTo(c,"axisIntZoomed",this.handleValueAxisZoom);c.id||(c.id="valueAxisAuto"+b+"_"+(new Date).getTime());void 0===c.usePrefixes&&(c.usePrefixes=this.usePrefixes)}},processGuides:function(){var a=this.guides,b=this.categoryAxis;if(a)for(var c=0;c<a.length;c++){var e=a[c];(void 0!==e.category||void 0!==e.date)&&b&&b.addGuide(e);e.id||(e.id="guideAuto"+c+"_"+(new Date).getTime());var h=e.valueAxis;h?(d.isString(h)&&(h=this.getValueAxisById(h)),h?h.addGuide(e):this.valueAxes[0].addGuide(e)):isNaN(e.value)||this.valueAxes[0].addGuide(e)}},processGraphs:function(){var a=this.graphs,b;this.graphsById={};for(b=0;b<a.length;b++){var c=a[b],c=d.processObject(c,d.AmGraph,this.theme);a[b]=c;this.chooseGraphColor(c,b);c.chart=this;c.init();d.isString(c.valueAxis)&&(c.valueAxis=this.getValueAxisById(c.valueAxis));c.valueAxis||(c.valueAxis=this.valueAxes[0]);c.id||(c.id="graphAuto"+b+"_"+(new Date).getTime());this.graphsById[c.id]=c}},formatString:function(a,b,c){var e=b.graph,h=e.valueAxis;h.duration&&b.values.value&&(h=d.formatDuration(b.values.value,h.duration,"",h.durationUnits,h.maxInterval,h.numberFormatter),a=a.split("[[value]]").join(h));a=d.massReplace(a,{"[[title]]":e.title,"[[description]]":b.description});a=c?d.fixNewLines(a):d.fixBrakes(a);return a=d.cleanFromEmpty(a)},getBalloonColor:function(a,b,c){var e=a.lineColor,h=a.balloonColor;c&&(h=e);c=a.fillColorsR;"object"==typeof c?e=c[0]:void 0!==c&&(e=c);b.isNegative&&(c=a.negativeLineColor,a=a.negativeFillColors,"object"==typeof a?c=a[0]:void 0!==a&&(c=a),void 0!==c&&(e=c));void 0!==b.color&&(e=b.color);void 0!==b.lineColor&&(e=b.lineColor);b=b.fillColors;void 0!==b&&(e=b,d.ifArray(b)&&(e=b[0]));void 0===h&&(h=e);return h},getGraphById:function(a){return d.getObjById(this.graphs,a)},getValueAxisById:function(a){return d.getObjById(this.valueAxes,a)},processFields:function(a,b,c){if(a.itemColors){var e=a.itemColors,h=b.index;b.color=h<e.length?e[h]:d.randomColor()}e="lineColor color alpha fillColors description bullet customBullet bulletSize bulletConfig url labelColor dashLength pattern gap className columnIndex".split(" ");for(h=0;h<e.length;h++){var f=e[h],g=a[f+"Field"];g&&(g=c[g],d.isDefined(g)&&(b[f]=g))}b.dataContext=c},chooseGraphColor:function(a,b){if(a.lineColor)a.lineColorR=a.lineColor;else{var c;c=this.colors.length>b?this.colors[b]:a.lineColorR?a.lineColorR:d.randomColor();a.lineColorR=c}a.fillColorsR=a.fillColors?a.fillColors:a.lineColorR;a.bulletBorderColorR=a.bulletBorderColor?a.bulletBorderColor:a.useLineColorForBulletBorder?a.lineColorR:a.bulletColor;a.bulletColorR=a.bulletColor?a.bulletColor:a.lineColorR;if(c=this.patterns)a.pattern=c[b]},handleLegendEvent:function(a){var b=a.type;if(a=a.dataItem){var c=a.hidden,d=a.showBalloon;switch(b){case"clickMarker":this.textClickEnabled&&(d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a));break;case"clickLabel":d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a);break;case"rollOverItem":c||this.highlightGraph(a);break;case"rollOutItem":c||this.unhighlightGraph();break;case"hideItem":this.hideGraph(a);break;case"showItem":this.showGraph(a)}}},highlightGraph:function(a){var b=this.graphs;if(b){var c,d=.2;this.legend&&(d=this.legend.rollOverGraphAlpha);if(1!=d)for(c=0;c<b.length;c++){var h=b[c];h!=a&&h.changeOpacity(d)}}},unhighlightGraph:function(){var a;this.legend&&(a=this.legend.rollOverGraphAlpha);if(1!=a){a=this.graphs;var b;for(b=0;b<a.length;b++)a[b].changeOpacity(1)}},showGraph:function(a){a.switchable&&(a.hidden=!1,this.dataChanged=!0,"xy"!=this.type&&(this.marginsUpdated=!1),this.chartCreated&&this.initChart())},hideGraph:function(a){a.switchable&&(this.dataChanged=!0,"xy"!=this.type&&(this.marginsUpdated=!1),a.hidden=!0,this.chartCreated&&this.initChart())},hideGraphsBalloon:function(a){a.showBalloon=!1;this.updateLegend()},showGraphsBalloon:function(a){a.showBalloon=!0;this.updateLegend()},updateLegend:function(){this.legend&&this.legend.invalidateSize()},resetAnimation:function(){var a=this.graphs;if(a){var b;for(b=0;b<a.length;b++)a[b].animationPlayed=!1}},animateAgain:function(){this.resetAnimation();this.validateNow()}})})();(function(){var d=window.AmCharts;d.TrendLine=d.Class({construct:function(a){this.cname="TrendLine";this.createEvents("click","rollOver","rollOut");this.isProtected=!1;this.dashLength=0;this.lineColor="#00CC00";this.lineThickness=this.lineAlpha=1;d.applyTheme(this,a,this.cname)},draw:function(){var a=this;a.destroy();var b=a.chart,c=b.container,e,h,f,g,k=a.categoryAxis,l=a.initialDate,m=a.initialCategory,p=a.finalDate,q=a.finalCategory,n=a.valueAxis,t=a.valueAxisX,r=a.initialXValue,w=a.finalXValue,z=a.initialValue,x=a.finalValue,u=n.recalculateToPercents,A=b.dataDateFormat;k&&(l&&(l=d.getDate(l,A,"fff"),a.initialDate=l,e=k.dateToCoordinate(l)),m&&(e=k.categoryToCoordinate(m)),p&&(p=d.getDate(p,A,"fff"),a.finalDate=p,h=k.dateToCoordinate(p)),q&&(h=k.categoryToCoordinate(q)));t&&!u&&(isNaN(r)||(e=t.getCoordinate(r)),isNaN(w)||(h=t.getCoordinate(w)));n&&!u&&(isNaN(z)||(f=n.getCoordinate(z)),isNaN(x)||(g=n.getCoordinate(x)));if(!(isNaN(e)||isNaN(h)||isNaN(f)||isNaN(f))){b.rotate?(k=[f,g],g=[e,h]):(k=[e,h],g=[f,g]);l=a.lineColor;f=d.line(c,k,g,l,a.lineAlpha,a.lineThickness,a.dashLength);e=k;h=g;q=k[1]-k[0];n=g[1]-g[0];0===q&&(q=.01);0===n&&(n=.01);m=q/Math.abs(q);p=n/Math.abs(n);n=90*Math.PI/180-Math.asin(q/(q*n/Math.abs(q*n)*Math.sqrt(Math.pow(q,2)+Math.pow(n,2))));q=Math.abs(5*Math.cos(n));n=Math.abs(5*Math.sin(n));e.push(k[1]-m*n,k[0]-m*n);h.push(g[1]+p*q,g[0]+p*q);g=d.polygon(c,e,h,l,.005,0);c=c.set([g,f]);c.translate(b.marginLeftReal,b.marginTopReal);b.trendLinesSet.push(c);d.setCN(b,f,"trend-line");d.setCN(b,f,"trend-line-"+a.id);a.line=f;a.set=c;if(f=a.initialImage)f=d.processObject(f,d.Image,a.theme),f.chart=b,f.draw(),f.translate(e[0]+f.offsetX,h[0]+f.offsetY),c.push(f.set);if(f=a.finalImage)f=d.processObject(f,d.Image,a.theme),f.chart=b,f.draw(),f.translate(e[1]+f.offsetX,h[1]+f.offsetY),c.push(f.set);g.mouseup(function(){a.handleLineClick()}).mouseover(function(){a.handleLineOver()}).mouseout(function(){a.handleLineOut()});g.touchend&&g.touchend(function(){a.handleLineClick()});c.clipRect(0,0,b.plotAreaWidth,b.plotAreaHeight)}},handleLineClick:function(){this.fire({type:"click",trendLine:this,chart:this.chart})},handleLineOver:function(){var a=this.rollOverColor;void 0!==a&&this.line.attr({stroke:a});this.balloonText&&(clearTimeout(this.chart.hoverInt),a=this.line.getBBox(),this.chart.showBalloon(this.balloonText,this.lineColor,!0,this.x+a.x+a.width/2,this.y+a.y+a.height/2));this.fire({type:"rollOver",trendLine:this,chart:this.chart})},handleLineOut:function(){this.line.attr({stroke:this.lineColor});this.balloonText&&this.chart.hideBalloon();this.fire({type:"rollOut",trendLine:this,chart:this.chart})},destroy:function(){d.remove(this.set)}})})();(function(){var d=window.AmCharts;d.Image=d.Class({construct:function(a){this.cname="Image";this.height=this.width=20;this.rotation=this.offsetY=this.offsetX=0;this.balloonColor=this.color="#000000";this.opacity=1;d.applyTheme(this,a,this.cname)},draw:function(){var a=this;a.set&&a.set.remove();var b=a.chart.container;a.set=b.set();var c,d;a.url?(c=b.image(a.url,0,0,a.width,a.height),d=1):a.svgPath&&(c=b.path(a.svgPath),c.setAttr("fill",a.color),c.setAttr("stroke",a.outlineColor),b=c.getBBox(),d=Math.min(a.width/b.width,a.height/b.height));c&&(c.setAttr("opacity",a.opacity),a.set.rotate(a.rotation),c.translate(-a.width/2,-a.height/2,d),a.balloonText&&c.mouseover(function(){a.chart.showBalloon(a.balloonText,a.balloonColor,!0)}).mouseout(function(){a.chart.hideBalloon()}).touchend(function(){a.chart.hideBalloon()}).touchstart(function(){a.chart.showBalloon(a.balloonText,a.balloonColor,!0)}),a.set.push(c))},translate:function(a,b){this.set&&this.set.translate(a,b)}})})();(function(){var d=window.AmCharts;d.circle=function(a,b,c,e,h,f,g,k,l){0>=b&&(b=.001);if(void 0==h||0===h)h=.01;void 0===f&&(f="#000000");void 0===g&&(g=0);e={fill:c,stroke:f,"fill-opacity":e,"stroke-width":h,"stroke-opacity":g};a=isNaN(l)?a.circle(0,0,b).attr(e):a.ellipse(0,0,b,l).attr(e);k&&a.gradient("radialGradient",[c,d.adjustLuminosity(c,-.6)]);return a};d.text=function(a,b,c,e,h,f,g,k){f||(f="middle");"right"==f&&(f="end");"left"==f&&(f="start");isNaN(k)&&(k=1);void 0!==b&&(b=String(b),d.isIE&&!d.isModern&&(b=b.replace("&","&"),b=b.replace("&","&")));c={fill:c,"font-family":e,"font-size":h+"px",opacity:k};!0===g&&(c["font-weight"]="bold");c["text-anchor"]=f;return a.text(b,c)};d.polygon=function(a,b,c,e,h,f,g,k,l,m,p){isNaN(f)&&(f=.01);isNaN(k)&&(k=h);var q=e,n=!1;"object"==typeof q&&1<q.length&&(n=!0,q=q[0]);void 0===g&&(g=q);h={fill:q,stroke:g,"fill-opacity":h,"stroke-width":f,"stroke-opacity":k};void 0!==p&&0<p&&(h["stroke-dasharray"]=p);p=d.dx;f=d.dy;a.handDrawn&&(c=d.makeHD(b,c,a.handDrawScatter),b=c[0],c=c[1]);g=Math.round;m&&(b[t]=d.roundTo(b[t],5),c[t]=d.roundTo(c[t],5),g=Number);k="M"+(g(b[0])+p)+","+(g(c[0])+f);for(var t=1;t<b.length;t++)m&&(b[t]=d.roundTo(b[t],5),c[t]=d.roundTo(c[t],5)),k+=" L"+(g(b[t])+p)+","+(g(c[t])+f);a=a.path(k+" Z").attr(h);n&&a.gradient("linearGradient",e,l);return a};d.rect=function(a,b,c,e,h,f,g,k,l,m,p){if(isNaN(b)||isNaN(c))return a.set();isNaN(f)&&(f=0);void 0===l&&(l=0);void 0===m&&(m=270);isNaN(h)&&(h=0);var q=e,n=!1;"object"==typeof q&&(q=q[0],n=!0);void 0===g&&(g=q);void 0===k&&(k=h);b=Math.round(b);c=Math.round(c);var t=0,r=0;0>b&&(b=Math.abs(b),t=-b);0>c&&(c=Math.abs(c),r=-c);t+=d.dx;r+=d.dy;h={fill:q,stroke:g,"fill-opacity":h,"stroke-opacity":k};void 0!==p&&0<p&&(h["stroke-dasharray"]=p);a=a.rect(t,r,b,c,l,f).attr(h);n&&a.gradient("linearGradient",e,m);return a};d.bullet=function(a,b,c,e,h,f,g,k,l,m,p,q,n){var t;"circle"==b&&(b="round");switch(b){case"round":t=d.circle(a,c/2,e,h,f,g,k);break;case"square":t=d.polygon(a,[-c/ -2,c/2,c/2,-c/2],[c/2,c/2,-c/2,-c/2],e,h,f,g,k,m-180,void 0,n);break;case"rectangle":t=d.polygon(a,[-c,c,c,-c],[c/2,c/2,-c/2,-c/2],e,h,f,g,k,m-180,void 0,n);break;case"diamond":t=d.polygon(a,[-c/2,0,c/2,0],[0,-c/2,0,c/2],e,h,f,g,k);break;case"triangleUp":t=d.triangle(a,c,0,e,h,f,g,k);break;case"triangleDown":t=d.triangle(a,c,180,e,h,f,g,k);break;case"triangleLeft":t=d.triangle(a,c,270,e,h,f,g,k);break;case"triangleRight":t=d.triangle(a,c,90,e,h,f,g,k);break;case"bubble":t=d.circle(a,c/2,e,h,f,g,k,!0);break;case"line":t=d.line(a,[-c/2,c/2],[0,0],e,h,f,g,k);break;case"yError":t=a.set();t.push(d.line(a,[0,0],[-c/2,c/2],e,h,f));t.push(d.line(a,[-l,l],[-c/2,-c/2],e,h,f));t.push(d.line(a,[-l,l],[c/2,c/2],e,h,f));break;case"xError":t=a.set(),t.push(d.line(a,[-c/2,c/2],[0,0],e,h,f)),t.push(d.line(a,[-c/2,-c/2],[-l,l],e,h,f)),t.push(d.line(a,[c/2,c/2],[-l,l],e,h,f))}t&&t.pattern(p,NaN,q);return t};d.triangle=function(a,b,c,d,h,f,g,k){if(void 0===f||0===f)f=1;void 0===g&&(g="#000");void 0===k&&(k=0);d={fill:d,stroke:g,"fill-opacity":h,"stroke-width":f,"stroke-opacity":k};b/=2;var l;0===c&&(l=" M"+-b+","+b+" L0,"+-b+" L"+b+","+b+" Z");180==c&&(l=" M"+-b+","+-b+" L0,"+b+" L"+b+","+-b+" Z");90==c&&(l=" M"+-b+","+-b+" L"+b+",0 L"+-b+","+b+" Z");270==c&&(l=" M"+-b+",0 L"+b+","+b+" L"+b+","+-b+" Z");return a.path(l).attr(d)};d.line=function(a,b,c,e,h,f,g,k,l,m,p){if(a.handDrawn&&!p)return d.handDrawnLine(a,b,c,e,h,f,g,k,l,m,p);f={fill:"none","stroke-width":f};void 0!==g&&0<g&&(f["stroke-dasharray"]=g);isNaN(h)||(f["stroke-opacity"]=h);e&&(f.stroke=e);e=Math.round;m&&(e=Number,b[0]=d.roundTo(b[0],5),c[0]=d.roundTo(c[0],5));m=d.dx;h=d.dy;g="M"+(e(b[0])+m)+","+(e(c[0])+h);for(k=1;k<b.length;k++)b[k]=d.roundTo(b[k],5),c[k]=d.roundTo(c[k],5),g+=" L"+(e(b[k])+m)+","+(e(c[k])+h);if(d.VML)return a.path(g,void 0,!0).attr(f);l&&(g+=" M0,0 L0,0");return a.path(g).attr(f)};d.makeHD=function(a,b,c){for(var d=[],h=[],f=1;f<a.length;f++)for(var g=Number(a[f-1]),k=Number(b[f-1]),l=Number(a[f]),m=Number(b[f]),p=Math.round(Math.sqrt(Math.pow(l-g,2)+Math.pow(m-k,2))/50)+1,l=(l-g)/p,m=(m-k)/p,q=0;q<=p;q++){var n=k+q*m+Math.random()*c;d.push(g+q*l+Math.random()*c);h.push(n)}return[d,h]};d.handDrawnLine=function(a,b,c,e,h,f,g,k,l,m){var p,q=a.set();for(p=1;p<b.length;p++)for(var n=[b[p-1],b[p]],t=[c[p-1],c[p]],t=d.makeHD(n,t,a.handDrawScatter),n=t[0],t=t[1],r=1;r<n.length;r++)q.push(d.line(a,[n[r-1],n[r]],[t[r-1],t[r]],e,h,f+Math.random()*a.handDrawThickness-a.handDrawThickness/2,g,k,l,m,!0));return q};d.doNothing= -function(a){return a};d.drop=function(a,b,c,d,h,f,g,k){var l=1/180*Math.PI,m=c-20,p=Math.sin(m*l)*b,q=Math.cos(m*l)*b,n=Math.sin((m+40)*l)*b,t=Math.cos((m+40)*l)*b,r=.8*b,w=-b/3,z=b/3;0===c&&(w=-w,z=0);180==c&&(z=0);90==c&&(w=0);270==c&&(w=0,z=-z);c={fill:d,stroke:g,"stroke-width":f,"stroke-opacity":k,"fill-opacity":h};b="M"+p+","+q+" A"+b+","+b+",0,1,1,"+n+","+t+(" A"+r+","+r+",0,0,0,"+(Math.sin((m+20)*l)*b+z)+","+(Math.cos((m+20)*l)*b+w));b+=" A"+r+","+r+",0,0,0,"+p+","+q;return a.path(b,void 0,void 0,"1000,1000").attr(c)};d.wedge=function(a,b,c,e,h,f,g,k,l,m,p,q,n,t){var r=Math.round;f=r(f);g=r(g);k=r(k);var w=r(g/f*k),z=d.VML,x=359.5+f/100;359.94<x&&(x=359.94);h>=x&&(h=x);var u=1/180*Math.PI,x=b+Math.sin(e*u)*k,A=c-Math.cos(e*u)*w,y=b+Math.sin(e*u)*f,B=c-Math.cos(e*u)*g,D=b+Math.sin((e+h)*u)*f,C=c-Math.cos((e+h)*u)*g,I=b+Math.sin((e+h)*u)*k,u=c-Math.cos((e+h)*u)*w,H={fill:d.adjustLuminosity(m.fill,-.2),"stroke-opacity":0,"fill-opacity":m["fill-opacity"]},Q=0;180<Math.abs(h)&&(Q=1);e=a.set();var M;z&&(x=r(10*x),y=r(10*y),D=r(10*D),I=r(10*I),A=r(10*A),B=r(10*B),C=r(10*C),u=r(10*u),b=r(10*b),l=r(10*l),c=r(10*c),f*=10,g*=10,k*=10,w*=10,1>Math.abs(h)&&1>=Math.abs(D-y)&&1>=Math.abs(C-B)&&(M=!0));h="";var P;q&&(H["fill-opacity"]=0,H["stroke-opacity"]=m["stroke-opacity"]/2,H.stroke=m.stroke);if(0<l){P=" M"+x+","+(A+l)+" L"+y+","+(B+l);z?(M||(P+=" A"+(b-f)+","+(l+c-g)+","+(b+f)+","+(l+c+g)+","+y+","+(B+l)+","+D+","+(C+l)),P+=" L"+I+","+(u+l),0<k&&(M||(P+=" B"+(b-k)+","+(l+c-w)+","+(b+k)+","+ -(l+c+w)+","+I+","+(l+u)+","+x+","+(l+A)))):(P+=" A"+f+","+g+",0,"+Q+",1,"+D+","+(C+l)+" L"+I+","+(u+l),0<k&&(P+=" A"+k+","+w+",0,"+Q+",0,"+x+","+(A+l)));P+=" Z";var ia=l;z&&(ia/=10);for(var J=0;J<ia;J+=10){var aa=a.path(P,void 0,void 0,"1000,1000").attr(H);e.push(aa);aa.translate(0,-J)}P=a.path(" M"+x+","+A+" L"+x+","+(A+l)+" L"+y+","+(B+l)+" L"+y+","+B+" L"+x+","+A+" Z",void 0,void 0,"1000,1000").attr(H);l=a.path(" M"+D+","+C+" L"+D+","+(C+l)+" L"+I+","+(u+l)+" L"+I+","+u+" L"+D+","+C+" Z",void 0,void 0,"1000,1000").attr(H);e.push(P);e.push(l)}z?(M||(h=" A"+r(b-f)+","+r(c-g)+","+r(b+f)+","+r(c+g)+","+r(y)+","+r(B)+","+r(D)+","+r(C)),g=" M"+r(x)+","+r(A)+" L"+r(y)+","+r(B)+h+" L"+r(I)+","+r(u)):g=" M"+x+","+A+" L"+y+","+B+(" A"+f+","+g+",0,"+Q+",1,"+D+","+C)+" L"+I+","+u;0<k&&(z?M||(g+=" B"+(b-k)+","+(c-w)+","+(b+k)+","+(c+w)+","+I+","+u+","+x+","+A):g+=" A"+k+","+w+",0,"+Q+",0,"+x+","+A);a.handDrawn&&(k=d.line(a,[x,y],[A,B],m.stroke,m.thickness*Math.random()*a.handDrawThickness,m["stroke-opacity"]),e.push(k));a=a.path(g+" Z",void 0,void 0,"1000,1000").attr(m);if(p){k=[];for(w=0;w<p.length;w++)k.push(d.adjustLuminosity(m.fill,p[w]));"radial"!=t||d.isModern||(k=[]);0<k.length&&a.gradient(t+"Gradient",k)}d.isModern&&"radial"==t&&a.grad&&(a.grad.setAttribute("gradientUnits","userSpaceOnUse"),a.grad.setAttribute("r",f),a.grad.setAttribute("cx",b),a.grad.setAttribute("cy",c));a.pattern(q,NaN,n);e.wedge=a;e.push(a);return e};d.rgb2hex=function(a){return(a=a.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===a.length?"#"+("0"+parseInt(a[1],10).toString(16)).slice(-2)+("0"+parseInt(a[2],10).toString(16)).slice(-2)+("0"+parseInt(a[3],10).toString(16)).slice(-2):""};d.adjustLuminosity=function(a,b){a&&-1!=a.indexOf("rgb")&&(a=d.rgb2hex(a));a=String(a).replace(/[^0-9a-f]/gi,"");6>a.length&&(a=String(a[0])+String(a[0])+String(a[1])+String(a[1])+String(a[2])+String(a[2]));b=b||0;var c="#",e,h;for(h=0;3>h;h++)e=parseInt(a.substr(2*h,2),16),e=Math.round(Math.min(Math.max(0,e+e*b),255)).toString(16),c+=("00"+ -e).substr(e.length);return c}})();(function(){var d=window.AmCharts;d.Bezier=d.Class({construct:function(a,b,c,e,h,f,g,k,l,m,p){var q=a.chart,n=d.bezierX,t=d.bezierY;isNaN(q.bezierX)||(n=q.bezierX);isNaN(q.bezierY)||(t=q.bezierY);isNaN(n)&&(q.rotate?(n=20,t=4):(t=20,n=4));var r,w;"object"==typeof g&&1<g.length&&(w=!0,r=g,g=g[0]);"object"==typeof k&&(k=k[0]);0===k&&(g="none");f={fill:g,"fill-opacity":k,"stroke-width":f};void 0!==l&&0<l&&(f["stroke-dasharray"]=l);isNaN(h)||(f["stroke-opacity"]=h);e&&(f.stroke=e);e="M"+Math.round(b[0])+","+Math.round(c[0])+" ";h=[];for(l=0;l<b.length;l++)isNaN(b[l])||isNaN(c[l])?(e+=this.drawSegment(h,n,t),l<b.length-1&&(e+="L"+b[l+1]+","+c[l+1]+" "),h=[]):h.push({x:Number(b[l]),y:Number(c[l])});e+=this.drawSegment(h,n,t);m?e+=m:d.VML||(e+="M0,0 L0,0");this.path=a.path(e).attr(f);this.node=this.path.node;w&&this.path.gradient("linearGradient",r,p)},drawSegment:function(a,b,c){var d="";if(2<a.length)for(var h=0;h<a.length-1;h++){var f=[],g=a[h-1],k=a[h],l=a[h+1],m=a[h+2];0===h?(f.push({x:k.x,y:k.y}),f.push({x:k.x,y:k.y}),f.push({x:l.x,y:l.y}),f.push({x:m.x,y:m.y})):h>=a.length-2?(f.push({x:g.x,y:g.y}),f.push({x:k.x,y:k.y}),f.push({x:l.x,y:l.y}),f.push({x:l.x,y:l.y})):(f.push({x:g.x,y:g.y}),f.push({x:k.x,y:k.y}),f.push({x:l.x,y:l.y}),f.push({x:m.x,y:m.y}));g=[];k=Math.round;g.push({x:k(f[1].x),y:k(f[1].y)});g.push({x:k((-f[0].x+b*f[1].x+f[2].x)/b),y:k((-f[0].y+c*f[1].y+f[2].y)/c)});g.push({x:k((f[1].x+b*f[2].x-f[3].x)/b),y:k((f[1].y+c*f[2].y-f[3].y)/c)});g.push({x:k(f[2].x),y:k(f[2].y)});d+="C"+ -g[1].x+","+g[1].y+","+g[2].x+","+g[2].y+","+g[3].x+","+g[3].y+" "}else 1<a.length&&(d+="L"+a[1].x+","+a[1].y);return d}})})();(function(){var d=window.AmCharts;d.AmDraw=d.Class({construct:function(a,b,c,e){d.SVG_NS="http://www.w3.org/2000/svg";d.SVG_XLINK="http://www.w3.org/1999/xlink";d.hasSVG=!!document.createElementNS&&!!document.createElementNS(d.SVG_NS,"svg").createSVGRect;1>b&&(b=10);1>c&&(c=10);this.div=a;this.width=b;this.height=c;this.rBin=document.createElement("div");d.hasSVG?(d.SVG=!0,b=this.createSvgElement("svg"),a.appendChild(b),this.container=b,this.addDefs(e),this.R=new d.SVGRenderer(this)):d.isIE&&d.VMLRenderer&&(d.VML=!0,d.vmlStyleSheet||(document.namespaces.add("amvml","urn:schemas-microsoft-com:vml"),31>document.styleSheets.length?(b=document.createStyleSheet(),b.addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true"),d.vmlStyleSheet=b):document.styleSheets[0].addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true")),this.container=a,this.R=new d.VMLRenderer(this,e),this.R.disableSelection(a))},createSvgElement:function(a){return document.createElementNS(d.SVG_NS,a)},circle:function(a,b,c,e){var h=new d.AmDObject("circle",this);h.attr({r:c,cx:a,cy:b});this.addToContainer(h.node,e);return h},ellipse:function(a,b,c,e,h){var f=new d.AmDObject("ellipse",this);f.attr({rx:c,ry:e,cx:a,cy:b});this.addToContainer(f.node,h);return f},setSize:function(a,b){0<a&&0<b&&(this.container.style.width=a+"px",this.container.style.height=b+"px")},rect:function(a,b,c,e,h,f,g){var k=new d.AmDObject("rect",this);d.VML&&(h=Math.round(100*h/Math.min(c,e)),c+=2*f,e+=2*f,k.bw=f,k.node.style.marginLeft=-f,k.node.style.marginTop=-f);1>c&&(c=1);1>e&&(e=1);k.attr({x:a,y:b,width:c,height:e,rx:h,ry:h,"stroke-width":f});this.addToContainer(k.node,g);return k},image:function(a,b,c,e,h,f){var g=new d.AmDObject("image",this);g.attr({x:b,y:c,width:e,height:h});this.R.path(g,a);this.addToContainer(g.node,f);return g},addToContainer:function(a,b){b||(b=this.container);b.appendChild(a)},text:function(a,b,c){return this.R.text(a,b,c)},path:function(a,b,c,e){var h=new d.AmDObject("path",this);e||(e="100,100");h.attr({cs:e});c?h.attr({dd:a}):h.attr({d:a});this.addToContainer(h.node,b);return h},set:function(a){return this.R.set(a)},remove:function(a){if(a){var b=this.rBin;b.appendChild(a);b.innerHTML=""}},renderFix:function(){var a=this.container,b=a.style;b.top="0px";b.left="0px";try{var c=a.getBoundingClientRect(),d=c.left-Math.round(c.left),h=c.top-Math.round(c.top);d&&(b.left=d+"px");h&&(b.top=h+"px")}catch(f){}},update:function(){this.R.update()},addDefs:function(a){if(d.hasSVG){var b=this.createSvgElement("desc"),c=this.container;c.setAttribute("version","1.1");c.style.position="absolute";this.setSize(this.width,this.height);if(a.accessibleTitle){var e=this.createSvgElement("text");c.appendChild(e);e.innerHTML=a.accessibleTitle;e.style.opacity=0}d.rtl&&(c.setAttribute("direction","rtl"),c.style.left="auto",c.style.right="0px");a&&(a.addCodeCredits&&b.appendChild(document.createTextNode("JavaScript chart by amCharts "+a.version)),c.appendChild(b),a.defs&&(b=this.createSvgElement("defs"),c.appendChild(b),d.parseDefs(a.defs,b),this.defs=b))}}})})();(function(){var d=window.AmCharts;d.AmDObject=d.Class({construct:function(a,b){this.D=b;this.R=b.R;this.node=this.R.create(this,a);this.y=this.x=0;this.scale=1},attr:function(a){this.R.attr(this,a);return this},getAttr:function(a){return this.node.getAttribute(a)},setAttr:function(a,b){this.R.setAttr(this,a,b);return this},clipRect:function(a,b,c,d){this.R.clipRect(this,a,b,c,d)},translate:function(a,b,c,d){d||(a=Math.round(a),b=Math.round(b));this.R.move(this,a,b,c);this.x=a;this.y=b;this.scale=c;this.angle&&this.rotate(this.angle)},rotate:function(a,b){this.R.rotate(this,a,b);this.angle=a},animate:function(a,b,c){for(var e in a)if(a.hasOwnProperty(e)){var h=e,f=a[e];c=d.getEffect(c);this.R.animate(this,h,f,b,c)}},push:function(a){if(a){var b=this.node;b.appendChild(a.node);var c=a.clipPath;c&&b.appendChild(c);(a=a.grad)&&b.appendChild(a)}},text:function(a){this.R.setText(this,a)},remove:function(){this.stop();this.R.remove(this)},clear:function(){var a=this.node;if(a.hasChildNodes())for(;1<=a.childNodes.length;)a.removeChild(a.firstChild)},hide:function(){this.setAttr("visibility","hidden")},show:function(){this.setAttr("visibility","visible")},getBBox:function(){return this.R.getBBox(this)},toFront:function(){var a=this.node;if(a){this.prevNextNode=a.nextSibling;var b=a.parentNode;b&&b.appendChild(a)}},toPrevious:function(){var a=this.node;a&&this.prevNextNode&&(a=a.parentNode)&&a.insertBefore(this.prevNextNode,null)},toBack:function(){var a=this.node;if(a){this.prevNextNode=a.nextSibling;var b=a.parentNode;if(b){var c=b.firstChild;c&&b.insertBefore(a,c)}}},mouseover:function(a){this.R.addListener(this,"mouseover",a);return this},mouseout:function(a){this.R.addListener(this,"mouseout",a);return this},click:function(a){this.R.addListener(this,"click",a);return this},dblclick:function(a){this.R.addListener(this,"dblclick",a);return this},mousedown:function(a){this.R.addListener(this,"mousedown",a);return this},mouseup:function(a){this.R.addListener(this,"mouseup",a);return this},touchmove:function(a){this.R.addListener(this,"touchmove",a);return this},touchstart:function(a){this.R.addListener(this,"touchstart",a);return this},touchend:function(a){this.R.addListener(this,"touchend",a);return this},keyup:function(a){this.R.addListener(this,"keyup",a);return this},focus:function(a){this.R.addListener(this,"focus",a);return this},blur:function(a){this.R.addListener(this,"blur",a);return this},contextmenu:function(a){this.node.addEventListener?this.node.addEventListener("contextmenu",a,!0):this.R.addListener(this,"contextmenu",a);return this},stop:function(){d.removeFromArray(this.R.animations,this.an_translate);d.removeFromArray(this.R.animations,this.an_y);d.removeFromArray(this.R.animations,this.an_x)},length:function(){return this.node.childNodes.length},gradient:function(a,b,c){this.R.gradient(this,a,b,c)},pattern:function(a,b,c){a&&this.R.pattern(this,a,b,c)}})})();(function(){var d=window.AmCharts;d.VMLRenderer=d.Class({construct:function(a,b){this.chart=b;this.D=a;this.cNames={circle:"oval",ellipse:"oval",rect:"roundrect",path:"shape"};this.styleMap={x:"left",y:"top",width:"width",height:"height","font-family":"fontFamily","font-size":"fontSize",visibility:"visibility"}},create:function(a,b){var c;if("group"==b)c=document.createElement("div"),a.type="div";else if("text"==b)c=document.createElement("div"),a.type="text";else if("image"==b)c=document.createElement("img"),a.type="image";else{a.type="shape";a.shapeType=this.cNames[b];c=document.createElement("amvml:"+this.cNames[b]);var d=document.createElement("amvml:stroke");c.appendChild(d);a.stroke=d;var h=document.createElement("amvml:fill");c.appendChild(h);a.fill=h;h.className="amvml";d.className="amvml";c.className="amvml"}c.style.position="absolute";c.style.top=0;c.style.left=0;return c},path:function(a,b){a.node.setAttribute("src",b)},setAttr:function(a,b,c){if(void 0!==c){var e;8===document.documentMode&&(e=!0);var h=a.node,f=a.type,g=h.style;"r"==b&&(g.width=2*c,g.height=2*c);"oval"==a.shapeType&&("rx"==b&&(g.width=2*c),"ry"==b&&(g.height=2*c));"roundrect"==a.shapeType&&("width"!=b&&"height"!=b||--c);"cursor"==b&&(g.cursor=c);"cx"==b&&(g.left=c-d.removePx(g.width)/2);"cy"==b&&(g.top=c-d.removePx(g.height)/2);var k=this.styleMap[b];"width"==k&&0>c&&(c=0);void 0!==k&&(g[k]=c);"text"==f&&("text-anchor"==b&&(a.anchor=c,k=h.clientWidth,"end"==c&&(g.marginLeft=-k+"px"),"middle"==c&&(g.marginLeft=-(k/2)+ -"px",g.textAlign="center"),"start"==c&&(g.marginLeft="0px")),"fill"==b&&(g.color=c),"font-weight"==b&&(g.fontWeight=c));if(g=a.children)for(k=0;k<g.length;k++)g[k].setAttr(b,c);if("shape"==f){"cs"==b&&(h.style.width="100px",h.style.height="100px",h.setAttribute("coordsize",c));"d"==b&&h.setAttribute("path",this.svgPathToVml(c));"dd"==b&&h.setAttribute("path",c);f=a.stroke;a=a.fill;"stroke"==b&&(e?f.color=c:f.setAttribute("color",c));"stroke-width"==b&&(e?f.weight=c:f.setAttribute("weight",c));"stroke-opacity"==b&&(e?f.opacity=c:f.setAttribute("opacity",c));"stroke-dasharray"==b&&(g="solid",0<c&&3>c&&(g="dot"),3<=c&&6>=c&&(g="dash"),6<c&&(g="longdash"),e?f.dashstyle=g:f.setAttribute("dashstyle",g));if("fill-opacity"==b||"opacity"==b)0===c?e?a.on=!1:a.setAttribute("on",!1):e?a.opacity=c:a.setAttribute("opacity",c);"fill"==b&&(e?a.color=c:a.setAttribute("color",c));"rx"==b&&(e?h.arcSize=c+"%":h.setAttribute("arcsize",c+"%"))}}},attr:function(a,b){for(var c in b)b.hasOwnProperty(c)&&this.setAttr(a,c,b[c])},text:function(a,b,c){var e=new d.AmDObject("text",this.D),h=e.node;h.style.whiteSpace="pre";h.innerHTML=a;this.D.addToContainer(h,c);this.attr(e,b);return e},getBBox:function(a){return this.getBox(a.node)},getBox:function(a){var b=a.offsetLeft,c=a.offsetTop,d=a.offsetWidth,h=a.offsetHeight,f;if(a.hasChildNodes()){var g,k,l;for(l=0;l<a.childNodes.length;l++){f=this.getBox(a.childNodes[l]);var m=f.x;isNaN(m)||(isNaN(g)?g=m:m<g&&(g=m));var p=f.y;isNaN(p)||(isNaN(k)?k=p:p<k&&(k=p));m=f.width+m;isNaN(m)||(d=Math.max(d,m));f=f.height+p;isNaN(f)||(h=Math.max(h,f))}0>g&&(b+=g);0>k&&(c+=k)}return{x:b,y:c,width:d,height:h}},setText:function(a,b){var c=a.node;c&&(c.innerHTML=b);this.setAttr(a,"text-anchor",a.anchor)},addListener:function(a,b,c){a.node["on"+b]=c},move:function(a,b,c){var e=a.node,h=e.style;"text"==a.type&&(c-=d.removePx(h.fontSize)/2-1);"oval"==a.shapeType&&(b-=d.removePx(h.width)/2,c-=d.removePx(h.height)/2);a=a.bw;isNaN(a)||(b-=a,c-=a);isNaN(b)||isNaN(c)||(e.style.left=b+"px",e.style.top= -c+"px")},svgPathToVml:function(a){var b=a.split(" ");a="";var c,d=Math.round,h;for(h=0;h<b.length;h++){var f=b[h],g=f.substring(0,1),f=f.substring(1),k=f.split(","),l=d(k[0])+","+d(k[1]);"M"==g&&(a+=" m "+l);"L"==g&&(a+=" l "+l);"Z"==g&&(a+=" x e");if("Q"==g){var m=c.length,p=c[m-1],q=k[0],n=k[1],l=k[2],t=k[3];c=d(c[m-2]/3+2/3*q);p=d(p/3+2/3*n);q=d(2/3*q+l/3);n=d(2/3*n+t/3);a+=" c "+c+","+p+","+q+","+n+","+l+","+t}"C"==g&&(a+=" c "+k[0]+","+k[1]+","+k[2]+","+k[3]+","+k[4]+","+k[5]);"A"==g&&(a+=" wa "+ -f);"B"==g&&(a+=" at "+f);c=k}return a},animate:function(a,b,c,d,h){var f=a.node,g=this.chart;a.animationFinished=!1;if("translate"==b){b=c.split(",");c=b[1];var k=f.offsetTop;g.animate(a,"left",f.offsetLeft,b[0],d,h,"px");g.animate(a,"top",k,c,d,h,"px")}},clipRect:function(a,b,c,d,h){a=a.node;0===b&&0===c?(a.style.width=d+"px",a.style.height=h+"px",a.style.overflow="hidden"):a.style.clip="rect("+c+"px "+(b+d)+"px "+(c+h)+"px "+b+"px)"},rotate:function(a,b,c){if(0!==Number(b)){var e=a.node;a=e.style;c||(c=this.getBGColor(e.parentNode));a.backgroundColor=c;a.paddingLeft=1;c=b*Math.PI/180;var h=Math.cos(c),f=Math.sin(c),g=d.removePx(a.left),k=d.removePx(a.top),l=e.offsetWidth,e=e.offsetHeight;b/=Math.abs(b);a.left=g+l/2-l/2*Math.cos(c)-b*e/2*Math.sin(c)+3;a.top=k-b*l/2*Math.sin(c)+b*e/2*Math.sin(c);a.cssText=a.cssText+"; filter:progid:DXImageTransform.Microsoft.Matrix(M11='"+h+"', M12='"+-f+"', M21='"+f+"', M22='"+h+"', sizingmethod='auto expand');"}},getBGColor:function(a){var b="#FFFFFF";if(a.style){var c=a.style.backgroundColor;""!==c?b=c:a.parentNode&&(b=this.getBGColor(a.parentNode))}return b},set:function(a){var b=new d.AmDObject("group",this.D);this.D.container.appendChild(b.node);if(a){var c;for(c=0;c<a.length;c++)b.push(a[c])}return b},gradient:function(a,b,c,d){var h="";"radialGradient"==b&&(b="gradientradial",c.reverse());"linearGradient"==b&&(b="gradient");var f;for(f=0;f<c.length;f++)h+=Math.round(100*f/(c.length-1))+"% "+c[f],f<c.length-1&&(h+=",");a=a.fill;90==d?d=0:270==d?d=180:180==d?d=90:0===d&&(d=270);8===document.documentMode?(a.type=b,a.angle=d):(a.setAttribute("type",b),a.setAttribute("angle",d));h&&(a.colors.value=h)},remove:function(a){a.clipPath&&this.D.remove(a.clipPath);this.D.remove(a.node)},disableSelection:function(a){a.onselectstart=function(){return!1};a.style.cursor="default"},pattern:function(a,b,c,e){c=a.node;a=a.fill;var h="none";b.color&&(h=b.color);c.fillColor=h;b=b.url;d.isAbsolute(b)||(b=e+b);8===document.documentMode?(a.type="tile",a.src=b):(a.setAttribute("type","tile"),a.setAttribute("src",b))},update:function(){}})})();(function(){var d=window.AmCharts;d.SVGRenderer=d.Class({construct:function(a){this.D=a;this.animations=[]},create:function(a,b){return document.createElementNS(d.SVG_NS,b)},attr:function(a,b){for(var c in b)b.hasOwnProperty(c)&&this.setAttr(a,c,b[c])},setAttr:function(a,b,c){void 0!==c&&a.node.setAttribute(b,c)},animate:function(a,b,c,e,h){a.animationFinished=!1;var f=a.node;a["an_"+b]&&d.removeFromArray(this.animations,a["an_"+b]);"translate"==b?(f=(f=f.getAttribute("transform"))?String(f).substring(10,f.length-1):"0,0",f=f.split(", ").join(" "),f=f.split(" ").join(","),0===f&&(f="0,0")):f=Number(f.getAttribute(b));c={obj:a,frame:0,attribute:b,from:f,to:c,time:e,effect:h};this.animations.push(c);a["an_"+b]=c},update:function(){var a,b=this.animations;for(a=b.length-1;0<=a;a--){var c=b[a],e=c.time*d.updateRate,h=c.frame+1,f=c.obj,g=c.attribute,k,l,m;if(h<=e){c.frame++;if("translate"==g){k=c.from.split(",");g=Number(k[0]);k=Number(k[1]);isNaN(k)&&(k=0);l=c.to.split(",");m=Number(l[0]);l=Number(l[1]);m=0===m-g?m:Math.round(d[c.effect](0,h,g,m-g,e));c=0===l-k?l:Math.round(d[c.effect](0,h,k,l-k,e));g="transform";if(isNaN(m)||isNaN(c))continue;c="translate("+m+","+c+")"}else l=Number(c.from),k=Number(c.to),m=k-l,c=d[c.effect](0,h,l,m,e),isNaN(c)&&(c=k),0===m&&this.animations.splice(a,1);this.setAttr(f,g,c)}else"translate"==g?(l=c.to.split(","),m=Number(l[0]),l=Number(l[1]),f.translate(m,l)):(k=Number(c.to),this.setAttr(f,g,k)),f.animationFinished=!0,this.animations.splice(a,1)}},getBBox:function(a){if(a=a.node)try{return a.getBBox()}catch(b){}return{width:0,height:0,x:0,y:0}},path:function(a,b){a.node.setAttributeNS(d.SVG_XLINK,"xlink:href",b)},clipRect:function(a,b,c,e,h){var f=a.node,g=a.clipPath;g&&this.D.remove(g);var k=f.parentNode;k&&(f=document.createElementNS(d.SVG_NS,"clipPath"),g=d.getUniqueId(),f.setAttribute("id",g),this.D.rect(b,c,e,h,0,0,f),k.appendChild(f),b="#",d.baseHref&&!d.isIE&&(b=this.removeTarget(window.location.href)+b),this.setAttr(a,"clip-path","url("+b+g+")"),this.clipPathC++,a.clipPath=f)},text:function(a,b,c){var e=new d.AmDObject("text",this.D);a=String(a).split("\n");var h=d.removePx(b["font-size"]),f;for(f=0;f<a.length;f++){var g=this.create(null,"tspan");g.appendChild(document.createTextNode(a[f]));g.setAttribute("y",(h+2)*f+Math.round(h/2));g.setAttribute("x",0);e.node.appendChild(g)}e.node.setAttribute("y",Math.round(h/2));this.attr(e,b);this.D.addToContainer(e.node,c);return e},setText:function(a,b){var c=a.node;c&&(c.removeChild(c.firstChild),c.appendChild(document.createTextNode(b)))},move:function(a,b,c,d){isNaN(b)&&(b=0);isNaN(c)&&(c=0);b="translate("+b+","+c+")";d&&(b=b+" scale("+d+")");this.setAttr(a,"transform",b)},rotate:function(a,b){var c=a.node.getAttribute("transform"),d="rotate("+b+")";c&&(d=c+" "+d);this.setAttr(a,"transform",d)},set:function(a){var b=new d.AmDObject("g",this.D);this.D.container.appendChild(b.node);if(a){var c;for(c=0;c<a.length;c++)b.push(a[c])}return b},addListener:function(a,b,c){a.node["on"+b]=c},gradient:function(a,b,c,e){var h=a.node,f=a.grad;f&&this.D.remove(f);b=document.createElementNS(d.SVG_NS,b);f=d.getUniqueId();b.setAttribute("id",f);if(!isNaN(e)){var g=0,k=0,l=0,m=0;90==e?l=100:270==e?m=100:180==e?g=100:0===e&&(k=100);b.setAttribute("x1",g+"%");b.setAttribute("x2",k+"%");b.setAttribute("y1",l+"%");b.setAttribute("y2",m+"%")}for(e=0;e<c.length;e++)g=document.createElementNS(d.SVG_NS,"stop"),k=100*e/(c.length-1),0===e&&(k=0),g.setAttribute("offset",k+"%"),g.setAttribute("stop-color",c[e]),b.appendChild(g);h.parentNode.appendChild(b);c="#";d.baseHref&&!d.isIE&&(c=this.removeTarget(window.location.href)+c);h.setAttribute("fill","url("+c+f+")");a.grad=b},removeTarget:function(a){return a.split("#")[0]},pattern:function(a,b,c,e){var h=a.node;isNaN(c)&&(c=1);var f=a.patternNode;f&&this.D.remove(f);var f=document.createElementNS(d.SVG_NS,"pattern"),g=d.getUniqueId(),k=b;b.url&&(k=b.url);d.isAbsolute(k)||-1!=k.indexOf("data:image")||(k=e+k);e=Number(b.width);isNaN(e)&&(e=4);var l=Number(b.height);isNaN(l)&&(l=4);e/=c;l/=c;c=b.x;isNaN(c)&&(c=0);var m=-Math.random()*Number(b.randomX);isNaN(m)||(c=m);m=b.y;isNaN(m)&&(m=0);var p=-Math.random()*Number(b.randomY);isNaN(p)||(m=p);f.setAttribute("id",g);f.setAttribute("width",e);f.setAttribute("height",l);f.setAttribute("patternUnits","userSpaceOnUse");f.setAttribute("xlink:href",k);b.color&&(p=document.createElementNS(d.SVG_NS,"rect"),p.setAttributeNS(null,"height",e),p.setAttributeNS(null,"width",l),p.setAttributeNS(null,"fill",b.color),f.appendChild(p));this.D.image(k,0,0,e,l,f).translate(c,m);k="#";d.baseHref&&!d.isIE&&(k=this.removeTarget(window.location.href)+k);h.setAttribute("fill","url("+k+g+")");a.patternNode=f;h.parentNode.appendChild(f)},remove:function(a){a.clipPath&&this.D.remove(a.clipPath);a.grad&&this.D.remove(a.grad);a.patternNode&&this.D.remove(a.patternNode);this.D.remove(a.node)}})})();(function(){var d=window.AmCharts;d.AmLegend=d.Class({construct:function(a){this.enabled=!0;this.cname="AmLegend";this.createEvents("rollOverMarker","rollOverItem","rollOutMarker","rollOutItem","showItem","hideItem","clickMarker","clickLabel");this.position="bottom";this.borderColor=this.color="#000000";this.borderAlpha=0;this.markerLabelGap=5;this.verticalGap=10;this.align="left";this.horizontalGap=0;this.spacing=10;this.markerDisabledColor="#AAB3B3";this.markerType="square";this.markerSize=16;this.markerBorderThickness=this.markerBorderAlpha=1;this.marginBottom=this.marginTop=0;this.marginLeft=this.marginRight=20;this.autoMargins=!0;this.valueWidth=50;this.switchable=!0;this.switchType="x";this.switchColor="#FFFFFF";this.rollOverColor="#CC0000";this.reversedOrder=!1;this.labelText="[[title]]";this.valueText="[[value]]";this.accessibleLabel="[[title]]";this.useMarkerColorForLabels=!1;this.rollOverGraphAlpha=1;this.textClickEnabled=!1;this.equalWidths=!0;this.backgroundColor="#FFFFFF";this.backgroundAlpha=0;this.useGraphSettings=!1;this.showEntries=!0;this.labelDx=0;d.applyTheme(this,a,this.cname)},setData:function(a){this.legendData=a;this.invalidateSize()},invalidateSize:function(){this.destroy();this.entries=[];this.valueLabels=[];var a=this.legendData;this.enabled&&(d.ifArray(a)||d.ifArray(this.data))&&this.drawLegend()},drawLegend:function(){var a=this.chart,b=this.position,c=this.width,e=a.divRealWidth,h=a.divRealHeight,f=this.div,g=this.legendData;this.data&&(g=this.combineLegend?this.legendData.concat(this.data):this.data);isNaN(this.fontSize)&&(this.fontSize=a.fontSize);this.maxColumnsReal=this.maxColumns;if("right"==b||"left"==b)this.maxColumnsReal=1,this.autoMargins&&(this.marginLeft=this.marginRight=10);else if(this.autoMargins){this.marginRight=a.marginRight;this.marginLeft=a.marginLeft;var k=a.autoMarginOffset;"bottom"==b?(this.marginBottom=k,this.marginTop=0):(this.marginTop=k,this.marginBottom=0)}c=void 0!==c?d.toCoordinate(c,e):"right"!=b&&"left"!=b?a.realWidth:0<this.ieW?this.ieW:a.realWidth;"outside"==b?(c=f.offsetWidth,h=f.offsetHeight,f.clientHeight&&(c=f.clientWidth,h=f.clientHeight)):(isNaN(c)||(f.style.width=c+"px"),f.className="amChartsLegend "+a.classNamePrefix+"-legend-div");this.divWidth=c;(b=this.container)?(b.container.innerHTML="",f.appendChild(b.container),b.width=c,b.height=h,b.setSize(c,h),b.addDefs(a)):b=new d.AmDraw(f,c,h,a);this.container=b;this.lx=0;this.ly=8;h=this.markerSize;h>this.fontSize&&(this.ly=h/2-1);0<h&&(this.lx+=h+this.markerLabelGap);this.titleWidth=0;if(h=this.title)h=d.text(this.container,h,this.color,a.fontFamily,this.fontSize,"start",!0),d.setCN(a,h,"legend-title"),h.translate(this.marginLeft,this.marginTop+this.verticalGap+this.ly+1),a=h.getBBox(),this.titleWidth=a.width+15,this.titleHeight=a.height+6;this.index=this.maxLabelWidth=0;if(this.showEntries){for(a=0;a<g.length;a++)this.createEntry(g[a]);for(a=this.index=0;a<g.length;a++)this.createValue(g[a])}this.arrangeEntries();this.updateValues()},arrangeEntries:function(){var a=this.position,b=this.marginLeft+ -this.titleWidth,c=this.marginRight,e=this.marginTop,h=this.marginBottom,f=this.horizontalGap,g=this.div,k=this.divWidth,l=this.maxColumnsReal,m=this.verticalGap,p=this.spacing,q=k-c-b,n=0,t=0,r=this.container;this.set&&this.set.remove();var w=r.set();this.set=w;var z=r.set();w.push(z);var x=this.entries,u,A;for(A=0;A<x.length;A++){u=x[A].getBBox();var y=u.width;y>n&&(n=y);u=u.height;u>t&&(t=u)}var y=t=0,B=f,D=0,C=0;for(A=0;A<x.length;A++){var I=x[A];this.reversedOrder&&(I=x[x.length-A-1]);u=I.getBBox();var H;this.equalWidths?H=y*(n+p+this.markerLabelGap):(H=B,B=B+u.width+f+p);H+u.width>q&&0<A&&0!==y&&(t++,H=y=0,B=H+u.width+f+p,D=D+C+m,C=0);u.height>C&&(C=u.height);I.translate(H,D);y++;!isNaN(l)&&y>=l&&(y=0,t++,D=D+C+m,B=f,C=0);z.push(I)}u=z.getBBox();l=u.height+2*m-1;"left"==a||"right"==a?(p=u.width+2*f,k=p+b+c,g.style.width=k+"px",this.ieW=k):p=k-b-c-1;c=d.polygon(this.container,[0,p,p,0],[0,0,l,l],this.backgroundColor,this.backgroundAlpha,1,this.borderColor,this.borderAlpha);d.setCN(this.chart,c,"legend-bg");w.push(c);w.translate(b,e);c.toBack();b=f;if("top"==a||"bottom"==a||"absolute"==a||"outside"==a)"center"==this.align?b=f+(p-u.width)/2:"right"==this.align&&(b=f+p-u.width);z.translate(b,m+1);this.titleHeight>l&&(l=this.titleHeight);e=l+e+h+1;0>e&&(e=0);"absolute"!=a&&"outside"!=a&&e>this.chart.divRealHeight&&(g.style.top="0px");g.style.height=Math.round(e)+"px";r.setSize(this.divWidth,e)},createEntry:function(a){if(!1!==a.visibleInLegend&&!a.hideFromLegend){var b=this,c=b.chart,e=b.useGraphSettings, -h=a.markerType;h&&(e=!1);a.legendEntryWidth=b.markerSize;h||(h=b.markerType);var f=a.color,g=a.alpha;a.legendKeyColor&&(f=a.legendKeyColor());a.legendKeyAlpha&&(g=a.legendKeyAlpha());var k;!0===a.hidden&&(k=f=b.markerDisabledColor);var l=a.pattern,m,p=a.customMarker;p||(p=b.customMarker);var q=b.container,n=b.markerSize,t=0,r=0,w=n/2;if(e){e=a.type;b.switchType=void 0;if("line"==e||"step"==e||"smoothedLine"==e||"ohlc"==e)m=q.set(),a.hidden||(f=a.lineColorR,k=a.bulletBorderColorR),t=d.line(q,[0,2*n],[n/2,n/2],f,a.lineAlpha,a.lineThickness,a.dashLength),d.setCN(c,t,"graph-stroke"),m.push(t),a.bullet&&(a.hidden||(f=a.bulletColorR),t=d.bullet(q,a.bullet,a.bulletSize,f,a.bulletAlpha,a.bulletBorderThickness,k,a.bulletBorderAlpha))&&(d.setCN(c,t,"graph-bullet"),t.translate(n+1,n/2),m.push(t)),w=0,t=n,r=n/3;else{a.getGradRotation&&(m=a.getGradRotation(),0===m&&(m=180));t=a.fillColorsR;!0===a.hidden&&(t=f);if(m=b.createMarker("rectangle",t,a.fillAlphas,a.lineThickness,f,a.lineAlpha,m,l,a.dashLength))w=n,m.translate(w,n/2);t=n}d.setCN(c,m,"graph-"+e);d.setCN(c,m,"graph-"+a.id)}else if(p)m=q.image(p,0,0,n,n);else{var z;isNaN(b.gradientRotation)||(z=180+b.gradientRotation);(m=b.createMarker(h,f,g,void 0,void 0,void 0,z,l))&&m.translate(n/2,n/2)}d.setCN(c,m,"legend-marker");b.addListeners(m,a);q=q.set([m]);b.switchable&&a.switchable&&q.setAttr("cursor","pointer");void 0!==a.id&&d.setCN(c,q,"legend-item-"+a.id);d.setCN(c,q,a.className,!0);k=b.switchType;var x;k&&"none"!=k&&0<n&&("x"==k?(x=b.createX(),x.translate(n/2,n/2)):x=b.createV(),x.dItem=a,!0!==a.hidden?"x"==k?x.hide():x.show():"x"!=k&&x.hide(),b.switchable||x.hide(),b.addListeners(x,a),a.legendSwitch=x,q.push(x),d.setCN(c,x,"legend-switch"));k=b.color;a.showBalloon&&b.textClickEnabled&&void 0!==b.selectedColor&&(k=b.selectedColor);b.useMarkerColorForLabels&&!l&&(k=f);!0===a.hidden&&(k=b.markerDisabledColor);f=d.massReplace(b.labelText,{"[[title]]":a.title});void 0!==b.tabIndex&&(q.setAttr("tabindex",b.tabIndex),q.setAttr("role","menuitem"),q.keyup(function(c){13==c.keyCode&&b.clickMarker(a,c)}));c.accessible&&b.accessibleLabel&&(l=d.massReplace(b.accessibleLabel,{"[[title]]":a.title}),c.makeAccessible(q,l));l=b.fontSize;m&&(n<=l&&(n=n/2+b.ly-l/2+(l+2-n)/2-r,m.translate(w,n),x&&x.translate(x.x,n)),a.legendEntryWidth=m.getBBox().width);var u;f&&(f=d.fixBrakes(f),a.legendTextReal=f,u=b.labelWidth,u=isNaN(u)?d.text(b.container,f,k,c.fontFamily,l,"start"):d.wrappedText(b.container,f,k,c.fontFamily,l,"start",!1,u,0),d.setCN(c,u,"legend-label"), -u.translate(b.lx+t,b.ly),q.push(u),b.labelDx=t,c=u.getBBox().width,b.maxLabelWidth<c&&(b.maxLabelWidth=c));b.entries[b.index]=q;a.legendEntry=b.entries[b.index];a.legendMarker=m;a.legendLabel=u;b.index++}},addListeners:function(a,b){var c=this;a&&a.mouseover(function(a){c.rollOverMarker(b,a)}).mouseout(function(a){c.rollOutMarker(b,a)}).click(function(a){c.clickMarker(b,a)})},rollOverMarker:function(a,b){this.switchable&&this.dispatch("rollOverMarker",a,b);this.dispatch("rollOverItem",a,b)},rollOutMarker:function(a,b){this.switchable&&this.dispatch("rollOutMarker",a,b);this.dispatch("rollOutItem",a,b)},clickMarker:function(a,b){this.switchable&&(!0===a.hidden?this.dispatch("showItem",a,b):this.dispatch("hideItem",a,b));this.dispatch("clickMarker",a,b)},rollOverLabel:function(a,b){a.hidden||this.textClickEnabled&&a.legendLabel&&a.legendLabel.attr({fill:this.rollOverColor});this.dispatch("rollOverItem",a,b)},rollOutLabel:function(a,b){if(!a.hidden&&this.textClickEnabled&&a.legendLabel){var c=this.color;void 0!==this.selectedColor&&a.showBalloon&&(c=this.selectedColor);this.useMarkerColorForLabels&&(c=a.lineColor,void 0===c&&(c=a.color));a.legendLabel.attr({fill:c})}this.dispatch("rollOutItem",a,b)},clickLabel:function(a,b){this.textClickEnabled?a.hidden||this.dispatch("clickLabel",a,b):this.switchable&&(!0===a.hidden?this.dispatch("showItem",a,b):this.dispatch("hideItem",a,b))},dispatch:function(a,b,c){a={type:a,dataItem:b,target:this,event:c,chart:this.chart};this.chart&&this.chart.handleLegendEvent(a);this.fire(a)},createValue:function(a){var b=this,c=b.fontSize,e=b.chart;if(!1!==a.visibleInLegend&&!a.hideFromLegend){var h=b.maxLabelWidth;b.forceWidth&&(h=b.labelWidth);b.equalWidths||(b.valueAlign="left");"left"==b.valueAlign&&a.legendLabel&&(h=a.legendLabel.getBBox().width);var f=h;if(b.valueText&&0<b.valueWidth){var g=b.color;b.useMarkerColorForValues&&(g=a.color,a.legendKeyColor&&(g=a.legendKeyColor()));!0===a.hidden&&(g=b.markerDisabledColor);var k=b.valueText,h=h+b.lx+b.labelDx+b.markerLabelGap+ -b.valueWidth,l="end";"left"==b.valueAlign&&(h-=b.valueWidth,l="start");g=d.text(b.container,k,g,b.chart.fontFamily,c,l);d.setCN(e,g,"legend-value");g.translate(h,b.ly);b.entries[b.index].push(g);f+=b.valueWidth+2*b.markerLabelGap;g.dItem=a;b.valueLabels.push(g)}b.index++;e=b.markerSize;e<c+7&&(e=c+7,d.VML&&(e+=3));c=b.container.rect(a.legendEntryWidth,0,f,e,0,0).attr({stroke:"none",fill:"#fff","fill-opacity":.005});c.dItem=a;b.entries[b.index-1].push(c);c.mouseover(function(c){b.rollOverLabel(a,c)}).mouseout(function(c){b.rollOutLabel(a,c)}).click(function(c){b.clickLabel(a,c)})}},createV:function(){var a=this.markerSize;return d.polygon(this.container,[a/5,a/2,a-a/5,a/2],[a/3,a-a/5,a/5,a/1.7],this.switchColor)},createX:function(){var a=(this.markerSize-4)/2,b={stroke:this.switchColor,"stroke-width":3},c=this.container,e=d.line(c,[-a,a],[-a,a]).attr(b),a=d.line(c,[-a,a],[a,-a]).attr(b);return this.container.set([e,a])},createMarker:function(a,b,c,e,h,f,g,k,l){var m=this.markerSize,p=this.container;h||(h=this.markerBorderColor);h|| -(h=b);isNaN(e)&&(e=this.markerBorderThickness);isNaN(f)&&(f=this.markerBorderAlpha);return d.bullet(p,a,m,b,c,e,h,f,m,g,k,this.chart.path,l)},validateNow:function(){this.invalidateSize()},updateValues:function(){var a=this.valueLabels,b=this.chart,c,e=this.data;if(a)for(c=0;c<a.length;c++){var h=a[c],f=h.dItem;f.periodDataItem=void 0;f.periodPercentDataItem=void 0;var g=" ";if(e)f.value?h.text(f.value):h.text("");else{var k=null;if(void 0!==f.type){var k=f.currentDataItem,l=this.periodValueText;f.legendPeriodValueText&&(l=f.legendPeriodValueText);f.legendPeriodValueTextR&&(l=f.legendPeriodValueTextR);k?(g=this.valueText,f.legendValueText&&(g=f.legendValueText),g=b.formatString(g,k)):l&&b.formatPeriodString&&(l=d.massReplace(l,{"[[title]]":f.title}),g=b.formatPeriodString(l,f))}else g=b.formatString(this.valueText,f);l=f;k&&(l=k);var m=this.valueFunction;m&&(g=m(l,g,b.periodDataItem));var p;this.useMarkerColorForLabels&&!k&&f.lastDataItem&&(k=f.lastDataItem);k?p=b.getBalloonColor(f,k):f.legendKeyColor&&(p=f.legendKeyColor());f.legendColorFunction&&(p=f.legendColorFunction(l,g,f.periodDataItem,f.periodPercentDataItem));h.text(g);if(!f.pattern&&(this.useMarkerColorForValues&&h.setAttr("fill",p),this.useMarkerColorForLabels)){if(h=f.legendMarker)h.setAttr("fill",p),h.setAttr("stroke",p);(f=f.legendLabel)&&f.setAttr("fill",p)}}}},renderFix:function(){if(!d.VML&&this.enabled){var a=this.container;a&&a.renderFix()}},destroy:function(){this.div.innerHTML="";d.remove(this.set)}})})();(function(){var d=window.AmCharts;d.formatMilliseconds=function(a,b){if(-1!=a.indexOf("fff")){var c=b.getMilliseconds(),d=String(c);10>c&&(d="00"+c);10<=c&&100>c&&(d="0"+c);a=a.replace(/fff/g,d)}return a};d.extractPeriod=function(a){var b=d.stripNumbers(a),c=1;b!=a&&(c=Number(a.slice(0,a.indexOf(b))));return{period:b,count:c}};d.getDate=function(a,b,c){return a instanceof Date?d.newDate(a,c):b&&isNaN(a)?d.stringToDate(a,b):new Date(a)};d.daysInMonth=function(a){return(new Date(a.getYear(),a.getMonth()+ -1,0)).getDate()};d.newDate=function(a,b){return b&&-1==b.indexOf("fff")?new Date(a):new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds(),a.getMilliseconds())};d.resetDateToMin=function(a,b,c,e){void 0===e&&(e=1);var h,f,g,k,l,m,p;d.useUTC?(h=a.getUTCFullYear(),f=a.getUTCMonth(),g=a.getUTCDate(),k=a.getUTCHours(),l=a.getUTCMinutes(),m=a.getUTCSeconds(),p=a.getUTCMilliseconds(),a=a.getUTCDay()):(h=a.getFullYear(),f=a.getMonth(),g=a.getDate(),k=a.getHours(),l=a.getMinutes(),m=a.getSeconds(),p=a.getMilliseconds(),a=a.getDay());switch(b){case"YYYY":h=Math.floor(h/c)*c;f=0;g=1;p=m=l=k=0;break;case"MM":f=Math.floor(f/c)*c;g=1;p=m=l=k=0;break;case"WW":g=a>=e?g-a+e:g-(7+a)+e;p=m=l=k=0;break;case"DD":p=m=l=k=0;break;case"hh":k=Math.floor(k/c)*c;p=m=l=0;break;case"mm":l=Math.floor(l/c)*c;p=m=0;break;case"ss":m=Math.floor(m/c)*c;p=0;break;case"fff":p=Math.floor(p/c)*c}d.useUTC?(a=new Date,a.setUTCFullYear(h,f,g),a.setUTCHours(k,l,m,p)):a=new Date(h,f,g,k,l,m,p);return a};d.getPeriodDuration=function(a,b){void 0===b&&(b=1);var c;switch(a){case"YYYY":c=316224E5;break;case"MM":c=26784E5;break;case"WW":c=6048E5;break;case"DD":c=864E5;break;case"hh":c=36E5;break;case"mm":c=6E4;break;case"ss":c=1E3;break;case"fff":c=1}return c*b};d.intervals={s:{nextInterval:"ss",contains:1E3},ss:{nextInterval:"mm",contains:60,count:0},mm:{nextInterval:"hh",contains:60,count:1},hh:{nextInterval:"DD",contains:24,count:2},DD:{nextInterval:"",contains:Infinity,count:3}};d.getMaxInterval=function(a,b){var c=d.intervals;return a>=c[b].contains?(a=Math.round(a/c[b].contains),b=c[b].nextInterval,d.getMaxInterval(a,b)):"ss"==b?c[b].nextInterval:b};d.dayNames="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");d.shortDayNames="Sun Mon Tue Wed Thu Fri Sat".split(" ");d.monthNames="January February March April May June July August September October November December".split(" ");d.shortMonthNames="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");d.getWeekNumber=function(a){a=new Date(a);a.setHours(0,0,0);a.setDate(a.getDate()+4-(a.getDay()||7));var b=new Date(a.getFullYear(),0,1);return Math.ceil(((a-b)/864E5+1)/7)};d.stringToDate=function(a,b){var c={},e=[{pattern:"YYYY",period:"year"},{pattern:"YY",period:"year"},{pattern:"MM",period:"month"},{pattern:"M",period:"month"},{pattern:"DD",period:"date"},{pattern:"D",period:"date"},{pattern:"JJ",period:"hours"},{pattern:"J",period:"hours"},{pattern:"HH",period:"hours"},{pattern:"H",period:"hours"}, -{pattern:"KK",period:"hours"},{pattern:"K",period:"hours"},{pattern:"LL",period:"hours"},{pattern:"L",period:"hours"},{pattern:"NN",period:"minutes"},{pattern:"N",period:"minutes"},{pattern:"SS",period:"seconds"},{pattern:"S",period:"seconds"},{pattern:"QQQ",period:"milliseconds"},{pattern:"QQ",period:"milliseconds"},{pattern:"Q",period:"milliseconds"}],h=!0,f=b.indexOf("AA");-1!=f&&(a.substr(f,2),"pm"==a.toLowerCase&&(h=!1));var f=b,g,k,l;for(l=0;l<e.length;l++)k=e[l].period,c[k]=0,"date"==k&&(c[k]=1);for(l=0;l<e.length;l++)if(g=e[l].pattern,k=e[l].period,-1!=b.indexOf(g)){var m=d.getFromDateString(g,a,f);b=b.replace(g,"");if("KK"==g||"K"==g||"LL"==g||"L"==g)h||(m+=12);c[k]=m}d.useUTC?(e=new Date,e.setUTCFullYear(c.year,c.month,c.date),e.setUTCHours(c.hours,c.minutes,c.seconds,c.milliseconds)):e=new Date(c.year,c.month,c.date,c.hours,c.minutes,c.seconds,c.milliseconds);return e};d.getFromDateString=function(a,b,c){if(void 0!==b)return c=c.indexOf(a),b=String(b),b=b.substr(c,a.length),"0"==b.charAt(0)&&(b=b.substr(1,b.length-1)),b=Number(b),isNaN(b)&&(b=0),-1!=a.indexOf("M")&&b--,b};d.formatDate=function(a,b,c){c||(c=d);var e,h,f,g,k,l,m,p,q=d.getWeekNumber(a);d.useUTC?(e=a.getUTCFullYear(),h=a.getUTCMonth(),f=a.getUTCDate(),g=a.getUTCDay(),k=a.getUTCHours(),l=a.getUTCMinutes(),m=a.getUTCSeconds(),p=a.getUTCMilliseconds()):(e=a.getFullYear(),h=a.getMonth(),f=a.getDate(),g=a.getDay(),k=a.getHours(),l=a.getMinutes(),m=a.getSeconds(),p=a.getMilliseconds());var n=String(e).substr(2,2),t="0"+g;b=b.replace(/W/g,q);q=k;24==q&&(q=0);var r=q;10>r&&(r="0"+r);b=b.replace(/JJ/g,r);b=b.replace(/J/g,q);r=k;0===r&&(r=24,-1!=b.indexOf("H")&&(f--,0===f&&(e=new Date(a),e.setDate(e.getDate()-1),h=e.getMonth(),f=e.getDate(),e=e.getFullYear())));a=h+1;9>h&&(a="0"+a);q=f;10>f&&(q="0"+f);var w=r;10>w&&(w="0"+w);b=b.replace(/HH/g,w);b=b.replace(/H/g,r);r=k;11<r&&(r-=12);w=r;10>w&&(w="0"+w);b=b.replace(/KK/g,w);b=b.replace(/K/g,r);r=k;0===r&&(r=12);12<r&&(r-=12);w=r;10>w&&(w="0"+w);b=b.replace(/LL/g,w);b=b.replace(/L/g,r);r=l;10>r&&(r="0"+r);b=b.replace(/NN/g,r);b=b.replace(/N/g,l);l=m;10>l&&(l="0"+l);b=b.replace(/SS/g,l);b=b.replace(/S/g,m);m=p;10>m?m="00"+m:100>m&&(m="0"+m);l=p;10>l&&(l="00"+l);b=b.replace(/A/g,"@A@");b=b.replace(/QQQ/g,m);b=b.replace(/QQ/g,l);b=b.replace(/Q/g,p);b=b.replace(/YYYY/g,"@IIII@");b=b.replace(/YY/g,"@II@");b=b.replace(/MMMM/g,"@XXXX@");b=b.replace(/MMM/g,"@XXX@");b=b.replace(/MM/g,"@XX@");b=b.replace(/M/g,"@X@");b=b.replace(/DD/g,"@RR@");b=b.replace(/D/g,"@R@");b=b.replace(/EEEE/g,"@PPPP@");b=b.replace(/EEE/g,"@PPP@");b=b.replace(/EE/g,"@PP@");b=b.replace(/E/g,"@P@");b=b.replace(/@IIII@/g,e);b=b.replace(/@II@/g,n);b=b.replace(/@XXXX@/g,c.monthNames[h]);b=b.replace(/@XXX@/g,c.shortMonthNames[h]);b=b.replace(/@XX@/g,a);b=b.replace(/@X@/g,h+1);b=b.replace(/@RR@/g,q);b=b.replace(/@R@/g,f);b=b.replace(/@PPPP@/g,c.dayNames[g]);b=b.replace(/@PPP@/g,c.shortDayNames[g]);b=b.replace(/@PP@/g,t);b=b.replace(/@P@/g,g);return b=12>k?b.replace(/@A@/g,c.amString):b.replace(/@A@/g,c.pmString)};d.changeDate=function(a,b,c,e,h){if(d.useUTC)return d.changeUTCDate(a,b,c,e,h);var f=-1;void 0===e&&(e=!0);void 0===h&&(h=!1);!0===e&&(f=1);switch(b){case"YYYY":a.setFullYear(a.getFullYear()+c*f);e||h||a.setDate(a.getDate()+1);break;case"MM":b=a.getMonth();a.setMonth(a.getMonth()+c*f);a.getMonth()>b+c*f&&a.setDate(a.getDate()-1);e||h||a.setDate(a.getDate()+1);break;case"DD":a.setDate(a.getDate()+c*f);break;case"WW":a.setDate(a.getDate()+c*f*7);break;case"hh":a.setHours(a.getHours()+c*f);break;case"mm":a.setMinutes(a.getMinutes()+ -c*f);break;case"ss":a.setSeconds(a.getSeconds()+c*f);break;case"fff":a.setMilliseconds(a.getMilliseconds()+c*f)}return a};d.changeUTCDate=function(a,b,c,d,h){var f=-1;void 0===d&&(d=!0);void 0===h&&(h=!1);!0===d&&(f=1);switch(b){case"YYYY":a.setUTCFullYear(a.getUTCFullYear()+c*f);d||h||a.setUTCDate(a.getUTCDate()+1);break;case"MM":b=a.getUTCMonth();a.setUTCMonth(a.getUTCMonth()+c*f);a.getUTCMonth()>b+c*f&&a.setUTCDate(a.getUTCDate()-1);d||h||a.setUTCDate(a.getUTCDate()+1);break;case"DD":a.setUTCDate(a.getUTCDate()+ -c*f);break;case"WW":a.setUTCDate(a.getUTCDate()+c*f*7);break;case"hh":a.setUTCHours(a.getUTCHours()+c*f);break;case"mm":a.setUTCMinutes(a.getUTCMinutes()+c*f);break;case"ss":a.setUTCSeconds(a.getUTCSeconds()+c*f);break;case"fff":a.setUTCMilliseconds(a.getUTCMilliseconds()+c*f)}return a}})(); diff --git a/admin/src/main/resources/static/js/plugins/chart/export.css b/admin/src/main/resources/static/js/plugins/chart/export.css deleted file mode 100755 index 7ff4aa1716987247d4cd3eb210440ad5c89a9e44..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/export.css +++ /dev/null @@ -1 +0,0 @@ -.amcharts-export-canvas{position:absolute;display:none;z-index:1;top:0;right:0;bottom:0;left:0;background-color:#fff;}.amcharts-export-canvas.active{display:block;}.amcharts-export-menu{position:absolute;z-index:2;opacity:0.5;color:#000;}.amcharts-main-div:hover .amcharts-export-menu,.amcharts-stock-div:hover .amcharts-export-menu,.amcharts-export-menu.active{opacity:1;}.amcharts-export-menu-top-left>ul>li>ul:after{content:"";position:absolute;top:13px;right:100%;z-index:1000;border-top:7px solid transparent;border-left:7px solid transparent;border-right:7px solid #fff;border-bottom:7px solid transparent;}.amcharts-export-menu-top-left>ul>li>ul>li:first-child>a:after{content:"";position:absolute;top:12px;right:100%;z-index:1001;border-top:8px solid transparent;border-left:8px solid transparent;border-right:8px solid #e2e2e2;border-bottom:8px solid transparent;}.amcharts-export-menu-top-right>ul>li>ul:after{content:"";position:absolute;top:13px;left:100%;z-index:1000;border-top:7px solid transparent;border-left:7px solid #fff;border-right:7px solid transparent;border-bottom:7px solid transparent;}.amcharts-export-menu-top-right>ul>li>ul>li:first-child>a:after{content:"";position:absolute;top:12px;left:100%;z-index:1001;border-top:8px solid transparent;border-left:8px solid #e2e2e2;border-right:8px solid transparent;border-bottom:8px solid transparent;}.amcharts-export-menu-bottom-left>ul>li>ul:after{content:"";position:absolute;bottom:13px;right:100%;z-index:1000;border-top:7px solid transparent;border-left:7px solid transparent;border-right:7px solid #fff;border-bottom:7px solid transparent;}.amcharts-export-menu-bottom-left>ul>li>ul>li:last-child>a:after{content:"";position:absolute;bottom:12px;right:100%;z-index:1001;border-top:8px solid transparent;border-left:8px solid transparent;border-right:8px solid #e2e2e2;border-bottom:8px solid transparent;}.amcharts-export-menu-bottom-right>ul>li>ul:after{content:"";position:absolute;bottom:13px;left:100%;z-index:1000;border-top:7px solid transparent;border-left:7px solid #fff;border-right:7px solid transparent;border-bottom:7px solid transparent;}.amcharts-export-menu-bottom-right>ul>li>ul>li:last-child>a:after{content:"";position:absolute;bottom:12px;left:100%;z-index:1001;border-top:8px solid transparent;border-left:8px solid #e2e2e2;border-right:8px solid transparent;border-bottom:8px solid transparent;}.amcharts-export-menu ul{list-style:none;margin:0;padding:0;}.amcharts-export-menu li{position:relative;display:block;z-index:1;}.amcharts-export-menu li>ul{position:absolute;display:none;border:1px solid #e2e2e2;margin-top:-1px;background:#fff;}.amcharts-export-menu li>a{position:relative;display:block;color:#000;text-decoration:none;padding:12px 12px;z-index:2;white-space:nowrap;border-bottom:1px solid #f2f2f2;}.amcharts-export-menu li:last-child>a{border-bottom:none;}.amcharts-export-menu li>a>img{border:none;}.amcharts-export-menu-top-left{top:0;left:0;}.amcharts-export-menu-bottom-left{bottom:0;left:0;}.amcharts-export-menu-top-right{top:0;right:0;}.amcharts-export-menu-bottom-right{bottom:0;right:0;}.amcharts-export-menu li:hover>ul,.amcharts-export-menu li.active>ul{display:block;}.amcharts-export-menu li:hover>a,.amcharts-export-menu li.active>a{color:#fff;background-color:#636363;}.amcharts-export-menu-top-left li:hover>ul,.amcharts-export-menu-top-left li.active>ul{left:100%;top:0;}.amcharts-export-menu-bottom-left li:hover>ul,.amcharts-export-menu-bottom-left li.active>ul{left:100%;bottom:0;}.amcharts-export-menu-top-right li:hover>ul,.amcharts-export-menu-top-right li.active>ul{top:0;right:100%;}.amcharts-export-menu-bottom-right li:hover>ul,.amcharts-export-menu-bottom-right li.active>ul{bottom:0;right:100%;}.amcharts-export-menu .export-main>a,.amcharts-export-menu .export-drawing>a,.amcharts-export-menu .export-delayed-capturing>a{display:block;overflow:hidden;text-indent:-13333337px;width:36px;height:36px;padding:0;background-repeat:no-repeat;background-image:url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2211px%22%20height%3D%2214px%22%3E%3Cpath%20d%3D%22M3%2C0%20L8%2C0%20L8%2C5%20L11%2C5%20L5.5%2C10%20L0%2C5%20L3%2C5%20L03%2C0%22%20fill%3D%22%23888%22%2F%3E%3Crect%20x%3D%220%22%20y%3D%2212%22%20fill%3D%22%23888%22%20width%3D%2211%22%20height%3D%222%22%2F%3E%3C%2Fsvg%3E');background-color:#fff;background-position:center;-webkit-box-shadow:1px 1px 3px 0px rgba(0,0,0,0.5);-moz-box-shadow:1px 1px 3px 0px rgba(0,0,0,0.5);box-shadow:1px 1px 3px 0px rgba(0,0,0,0.5);border-radius:18px;margin:8px 8px 0 10px;}.amcharts-export-menu .export-drawing>a{background-image:url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%20width%3D%2216px%22%20height%3D%2217px%22%3E%3Crect%20x%3D%220%22%20y%3D%2216%22%20fill%3D%22%23888%22%20width%3D%2214%22%20height%3D%221%22%2F%3E%3Cpath%20transform%3D%22translate(-12%2C-10)%22%20fill%3D%22%23888%22%20d%3D%22M17.098%2C20.305c-0.142%2C0.146%2C0.101%2C0.04%2C0.137%2C0.004c0.027-0.028%2C0.204-0.09%2C0.484-0.09c0.338%2C0%2C0.626%2C0.092%2C0.787%2C0.255%20c0.473%2C0.472%2C0.424%2C0.932%2C0.393%2C1.078l-2.521%2C1.055l-1.577-1.577l1.054-2.52c0.039-0.009%2C0.105-0.018%2C0.188-0.018%20c0.219%2C0%2C0.555%2C0.069%2C0.893%2C0.407c0.378%2C0.378%2C0.246%2C1.188%2C0.166%2C1.271C17.062%2C20.207%2C17.062%2C20.269%2C17.098%2C20.305z%20M26.984%2C14.472c-0.008-0.674-0.61-1.257-1.31-1.933c-0.134-0.129-0.679-0.673-0.809-0.808c-0.679-0.702-1.266-1.31-1.943-1.31%20c-0.37%2C0-0.734%2C0.207-1.114%2C0.587l-6.852%2C6.847c-0.012%2C0.016-2.877%2C7.354-2.877%2C7.354c-0.012%2C0.032%2C0%2C0.063%2C0.022%2C0.091%20c0.021%2C0.021%2C0.044%2C0.029%2C0.067%2C0.029c0.01%2C0%2C0.018-0.003%2C0.028-0.007c0%2C0%2C7.357-2.864%2C7.369-2.877l6.854-6.847%20C26.803%2C15.216%2C26.988%2C14.848%2C26.984%2C14.472z%22%2F%3E%3C%2Fsvg%3E');}.amcharts-export-menu .export-main:hover,.amcharts-export-menu .export-drawing:hover,.amcharts-export-menu .export-main.active,.amcharts-export-menu .export-drawing.active{padding-bottom:100px;}.amcharts-export-menu.amcharts-export-menu-bottom-left .export-main:hover,.amcharts-export-menu.amcharts-export-menu-bottom-left .export-drawing:hover,.amcharts-export-menu.amcharts-export-menu-bottom-right .export-main:hover,.amcharts-export-menu.amcharts-export-menu-bottom-right .export-drawing:hover,.amcharts-export-menu.amcharts-export-menu-bottom-left .export-main.active,.amcharts-export-menu.amcharts-export-menu-bottom-left .export-drawing.active,.amcharts-export-menu.amcharts-export-menu-bottom-right .export-main.active,.amcharts-export-menu.amcharts-export-menu-bottom-right .export-drawing.active{padding-bottom:0;padding-top:100px;}.amcharts-export-menu .export-main:hover>a,.amcharts-export-menu .export-main.active>a{background-image:url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2211px%22%20height%3D%2214px%22%3E%3Cpath%20d%3D%22M3%2C0%20L8%2C0%20L8%2C5%20L11%2C5%20L5.5%2C10%20L0%2C5%20L3%2C5%20L03%2C0%22%20fill%3D%22%23fff%22%2F%3E%3Crect%20x%3D%220%22%20y%3D%2212%22%20fill%3D%22%23fff%22%20width%3D%2211%22%20height%3D%222%22%2F%3E%3C%2Fsvg%3E');}.amcharts-export-menu .export-drawing:hover>a,.amcharts-export-menu .export-drawing.active>a{background-image:url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%20width%3D%2216px%22%20height%3D%2217px%22%3E%3Crect%20x%3D%220%22%20y%3D%2216%22%20fill%3D%22%23FFF%22%20width%3D%2214%22%20height%3D%221%22%2F%3E%3Cpath%20transform%3D%22translate(-12%2C-10)%22%20fill%3D%22%23FFF%22%20d%3D%22M17.098%2C20.305c-0.142%2C0.146%2C0.101%2C0.04%2C0.137%2C0.004c0.027-0.028%2C0.204-0.09%2C0.484-0.09c0.338%2C0%2C0.626%2C0.092%2C0.787%2C0.255%20c0.473%2C0.472%2C0.424%2C0.932%2C0.393%2C1.078l-2.521%2C1.055l-1.577-1.577l1.054-2.52c0.039-0.009%2C0.105-0.018%2C0.188-0.018%20c0.219%2C0%2C0.555%2C0.069%2C0.893%2C0.407c0.378%2C0.378%2C0.246%2C1.188%2C0.166%2C1.271C17.062%2C20.207%2C17.062%2C20.269%2C17.098%2C20.305z%20M26.984%2C14.472c-0.008-0.674-0.61-1.257-1.31-1.933c-0.134-0.129-0.679-0.673-0.809-0.808c-0.679-0.702-1.266-1.31-1.943-1.31%20c-0.37%2C0-0.734%2C0.207-1.114%2C0.587l-6.852%2C6.847c-0.012%2C0.016-2.877%2C7.354-2.877%2C7.354c-0.012%2C0.032%2C0%2C0.063%2C0.022%2C0.091%20c0.021%2C0.021%2C0.044%2C0.029%2C0.067%2C0.029c0.01%2C0%2C0.018-0.003%2C0.028-0.007c0%2C0%2C7.357-2.864%2C7.369-2.877l6.854-6.847%20C26.803%2C15.216%2C26.988%2C14.848%2C26.984%2C14.472z%22%2F%3E%3C%2Fsvg%3E');}.amcharts-export-menu .export-close>a,.amcharts-export-menu .export-close:hover>a,.amcharts-export-menu .export-close.active>a{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAACXBIWXMAAAsTAAALEwEAmpwYAABBsGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS41LWMwMjEgNzkuMTU1NzcyLCAyMDE0LzAxLzEzLTE5OjQ0OjAwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDo4M2Q5NDllYS1lMjE3LTQ3Y2QtYTU1Ni04MTQ3NmRjNWEwYWQ8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjZhMTQ5MTc1LTNiODItMTE3OC05ZjZmLWY0MWMwNTYyYzQxYTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpkZGFhNTJkMi1mZDRiLTRkMmMtODEzOC01ZTEzNmQ4NGFjMDE8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6MDdhZmI1Y2UtYzQ1OS00YzQxLWJkMjItMTllMDJlMGE5YzVjPC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjA3YWZiNWNlLWM0NTktNGM0MS1iZDIyLTE5ZTAyZTBhOWM1Yzwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjgzZDk0OWVhLWUyMTctNDdjZC1hNTU2LTgxNDc2ZGM1YTBhZDwvc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8L3htcE1NOkRlcml2ZWRGcm9tPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6YmY3ZmRlNGYtZDk2MS00Njk4LWI0ZjAtMDJlYjEwOWE4OTA4PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTE1VDEzOjE3OjQ5KzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAyMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNvbnZlcnRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5mcm9tIGltYWdlL3BuZyB0byBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+ZGVyaXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5jb252ZXJ0ZWQgZnJvbSBpbWFnZS9wbmcgdG8gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcDwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6MDdhZmI1Y2UtYzQ1OS00YzQxLWJkMjItMTllMDJlMGE5YzVjPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTE1VDEzOjE3OjQ5KzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAyMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmRkYWE1MmQyLWZkNGItNGQyYy04MTM4LTVlMTM2ZDg0YWMwMTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNS0xNVQxMzoyMToyMSswMjowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMjEgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNS0wNS0xNVQxMzoxMzoxNyswMjowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE1LTA1LTE1VDEzOjIxOjIxKzAyOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNS0wNS0xNVQxMzoyMToyMSswMjowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPgogICAgICAgICAgICA8cmRmOkJhZz4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxwaG90b3Nob3A6TGF5ZXJOYW1lPlg8L3Bob3Rvc2hvcDpMYXllck5hbWU+CiAgICAgICAgICAgICAgICAgIDxwaG90b3Nob3A6TGF5ZXJUZXh0Plg8L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjY1NTM1PC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMzwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xNjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+HyMp+AAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAA3UlEQVR42rSSXZECQQyEPygMrIVFAidhkQASQEIjYVsCSOAksBJAAlhAwvKSWcJBUQVVl6fM5Ke7k4z6vudTG/OFTQAktcAs/ja2TyVBUgVsgQq42F5PItYBCn8PTFNjAYvw5wM92x3gCNSSFCh1araLvAdNBi53VgMtgCuweRqE7RyogAPQxHsdcQBGf0cuaZ80APzaXn468urtniQ1CaXoayStct5AL4QfgToKfoBzIF2BadGVkVZRkIU7UdQDkqRZoDwJl3ROzea2u4LUvtpHOavkty9H/m9XfhsA0l9VuzQDWrIAAAAASUVORK5CYII=);}.amcharts-export-menu .export-drawing-color{background:#000;width:35px;}.amcharts-export-menu .export-drawing-color>a{display:block;overflow:hidden;text-indent:-13333337px;}.amcharts-export-menu .export-drawing-color-red{background:#f00;}.amcharts-export-menu .export-drawing-color-green{background:#0f0;}.amcharts-export-menu .export-drawing-color-blue{background:#00f;}.amcharts-export-menu .export-drawing-color-white{background:#fff;}.amcharts-export-fallback{position:absolute;top:0;right:0;bottom:0;left:0;background-color:#fff;}.amcharts-export-fallback textarea{border:none;outline:none;position:absolute;overflow:hidden;width:100%;height:100%;padding:20px;}.amcharts-export-fallback-message{position:absolute;z-index:1;padding:20px;width:100%;background-color:#fff;}.amcharts-export-menu .export-delayed-capturing>a{text-indent:0px;line-height:36px;vertical-align:middle;text-align:center;background-image:none;}.amcharts-export-menu,.amcharts-export-canvas .canvas-container{-webkit-transition:opacity 0.5s ease-out;-moz-transition:opacity 0.5s ease-out;-ms-transition:opacity 0.5s ease-out;-o-transition:opacity 0.5s ease-out;transition:opacity 0.5s ease-out;}.amcharts-export-canvas.dropbox .canvas-container{opacity:0.5;}.amcharts-export-menu .export-drawing-shape a{font:0/0 a;text-shadow:none;color:transparent;}.amcharts-export-menu li img{height:20px;}.amcharts-export-menu .export-drawing-width a{text-align:center;}.amcharts-export-menu .export-drawing-width span{display:block;margin:0 auto;}.amcharts-export-menu .export-drawing-width span>span{display:block;background:#000;border-radius:100%;}.amcharts-export-menu .export-drawing-shape a:hover img,.amcharts-export-menu .export-drawing-shape.active a img{-webkit-filter:invert(100%);filter:invert(100%);} diff --git a/admin/src/main/resources/static/js/plugins/chart/export.min.js b/admin/src/main/resources/static/js/plugins/chart/export.min.js deleted file mode 100755 index b26964a9f70e9b123d834e42cf7711620077c1e7..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/export.min.js +++ /dev/null @@ -1 +0,0 @@ -AmCharts.translations.export||(AmCharts.translations.export={}),AmCharts.translations.export.en||(AmCharts.translations.export.en={"fallback.save.text":"CTRL + C to copy the data into the clipboard.","fallback.save.image":"Rightclick -> Save picture as... to save the image.","capturing.delayed.menu.label":"{{duration}}","capturing.delayed.menu.title":"Click to cancel","menu.label.print":"Print","menu.label.undo":"Undo","menu.label.redo":"Redo","menu.label.cancel":"Cancel","menu.label.save.image":"Download as ...","menu.label.save.data":"Save as ...","menu.label.draw":"Annotate ...","menu.label.draw.change":"Change ...","menu.label.draw.add":"Add ...","menu.label.draw.shapes":"Shape ...","menu.label.draw.colors":"Color ...","menu.label.draw.widths":"Size ...","menu.label.draw.opacities":"Opacity ...","menu.label.draw.text":"Text","menu.label.draw.modes":"Mode ...","menu.label.draw.modes.pencil":"Pencil","menu.label.draw.modes.line":"Line","menu.label.draw.modes.arrow":"Arrow","label.saved.from":"Saved from: "}),function(){AmCharts.export=function(e,t){var a,i={name:"export",version:"1.4.72",libs:{async:!0,autoLoad:!0,reload:!1,resources:["fabric.js/fabric.min.js","FileSaver.js/FileSaver.min.js",{"jszip/jszip.min.js":["xlsx/xlsx.min.js"],"pdfmake/pdfmake.min.js":["pdfmake/vfs_fonts.js"]}],namespaces:{"pdfmake.min.js":"pdfMake","jszip.min.js":"JSZip","xlsx.min.js":"XLSX","fabric.min.js":"fabric","FileSaver.min.js":"saveAs"},loadTimeout:1e4},config:{},setup:{chart:e,hasBlob:!1,wrapper:!1,isIE:!!window.document.documentMode,IEversion:window.document.documentMode,hasTouch:"object"==typeof window.Touch,focusedMenuItem:void 0},drawing:{enabled:!1,undos:[],redos:[],buffer:{position:{x1:0,y1:0,x2:0,y2:0,xD:0,yD:0}},handler:{undo:function(e,t){var a=i.drawing.undos.pop();if(a){a.selectable=!0,i.drawing.redos.push(a),"added"==a.action&&i.setup.fabric.remove(a.target);var r=JSON.parse(a.state);a.target.set(r),a.target instanceof fabric.Group&&i.drawing.handler.change({color:r.cfg.color,width:r.cfg.width,opacity:r.cfg.opacity},!0,a.target),i.setup.fabric.renderAll()}},redo:function(e,t){var a=i.drawing.redos.pop();if(a){a.selectable=!0,i.drawing.undos.push(a),"added"==a.action&&i.setup.fabric.add(a.target);var r=JSON.parse(a.state);a.target.recentState=a.state,a.target.set(r),a.target instanceof fabric.Group&&i.drawing.handler.change({color:r.cfg.color,width:r.cfg.width,opacity:r.cfg.opacity},!0,a.target),i.setup.fabric.renderAll()}},done:function(e){i.drawing.enabled=!1,i.drawing.buffer.enabled=!1,i.drawing.undos=[],i.drawing.redos=[],i.createMenu(i.config.menu),i.setup.fabric.deactivateAll(),i.isElement(i.setup.wrapper)&&i.isElement(i.setup.wrapper.parentNode)&&i.setup.wrapper.parentNode.removeChild&&(i.setup.wrapper.parentNode.removeChild(i.setup.wrapper),i.setup.wrapper=!1)},add:function(e){var t=i.deepMerge({top:i.setup.fabric.height/2,left:i.setup.fabric.width/2},e||{});(-1!=t.url.indexOf(".svg")?fabric.loadSVGFromURL:fabric.Image.fromURL)(t.url,function(e,a){var r=void 0!==a?fabric.util.groupSVGElements(e,a):e,n=!1;(r.height>i.setup.fabric.height||r.width>i.setup.fabric.width)&&(n=i.setup.fabric.height/2/r.height),t.top>i.setup.fabric.height&&(t.top=i.setup.fabric.height/2),t.left>i.setup.fabric.width&&(t.left=i.setup.fabric.width/2),i.drawing.buffer.isDrawing=!0,r.set({originX:"center",originY:"center",top:t.top,left:t.left,width:n?r.width*n:r.width,height:n?r.height*n:r.height,fill:i.drawing.color}),i.setup.fabric.add(r)})},change:function(e,t,a){var r,n,o,s=i.deepMerge({},e||{}),l=a||i.drawing.buffer.target,d=l?l._objects?l._objects:[l]:null;if(s.mode&&(i.drawing.mode=s.mode),s.width&&(i.drawing.width=s.width,i.drawing.fontSize=s.fontSize=3*s.width,1==i.drawing.width&&(i.drawing.fontSize=s.fontSize=i.defaults.fabric.drawing.fontSize)),s.fontSize&&(i.drawing.fontSize=s.fontSize),s.color&&(i.drawing.color=s.color),s.opacity&&(i.drawing.opacity=s.opacity),(o=i.getRGBA(i.drawing.color)).pop(),o.push(i.drawing.opacity),i.drawing.color="rgba("+o.join()+")",i.setup.fabric.freeDrawingBrush.color=i.drawing.color,i.setup.fabric.freeDrawingBrush.width=i.drawing.width,l){for((r=JSON.parse(l.recentState).cfg)&&(s.color=s.color||r.color,s.width=s.width||r.width,s.opacity=s.opacity||r.opacity,s.fontSize=s.fontSize||r.fontSize,(o=i.getRGBA(s.color)).pop(),o.push(s.opacity),s.color="rgba("+o.join()+")"),n=0;n<d.length;n++)d[n]instanceof fabric.Text||d[n]instanceof fabric.PathGroup||d[n]instanceof fabric.Triangle?((s.color||s.opacity)&&d[n].set({fill:s.color}),s.fontSize&&d[n].set({fontSize:s.fontSize})):(d[n]instanceof fabric.Path||d[n]instanceof fabric.Line)&&(l instanceof fabric.Group?(s.color||s.opacity)&&d[n].set({stroke:s.color}):((s.color||s.opacity)&&d[n].set({stroke:s.color}),s.width&&d[n].set({strokeWidth:s.width})));t||(r=JSON.stringify(i.deepMerge(l.saveState()._stateProperties,{cfg:{color:s.color,width:s.width,opacity:s.opacity}})),l.recentState=r,i.drawing.redos=[],i.drawing.undos.push({action:"modified",target:l,state:r})),i.setup.fabric.renderAll()}},text:function(e){var t=i.deepMerge({text:i.i18l("menu.label.draw.text"),top:i.setup.fabric.height/2,left:i.setup.fabric.width/2,fontSize:i.drawing.fontSize,fontFamily:i.setup.chart.fontFamily||"Verdana",fill:i.drawing.color},e||{});t.click=function(){};var a=new fabric.IText(t.text,t);return i.drawing.buffer.isDrawing=!0,i.setup.fabric.add(a),i.setup.fabric.setActiveObject(a),a.selectAll(),a.enterEditing(),a},line:function(e){var t,a,r,n,o=i.deepMerge({x1:i.setup.fabric.width/2-i.setup.fabric.width/10,x2:i.setup.fabric.width/2+i.setup.fabric.width/10,y1:i.setup.fabric.height/2,y2:i.setup.fabric.height/2,angle:90,strokeLineCap:i.drawing.lineCap,arrow:i.drawing.arrow,color:i.drawing.color,width:i.drawing.width,group:[]},e||{}),s=new fabric.Line([o.x1,o.y1,o.x2,o.y2],{stroke:o.color,strokeWidth:o.width,strokeLineCap:o.strokeLineCap});if(o.group.push(s),o.arrow&&(o.angle=o.angle?o.angle:i.getAngle(o.x1,o.y1,o.x2,o.y2),"start"==o.arrow?(r=o.y1+o.width/2,n=o.x1+o.width/2):"middle"==o.arrow?(r=o.y2+o.width/2-(o.y2-o.y1)/2,n=o.x2+o.width/2-(o.x2-o.x1)/2):(r=o.y2+o.width/2,n=o.x2+o.width/2),a=new fabric.Triangle({top:r,left:n,fill:o.color,height:7*o.width,width:7*o.width,angle:o.angle,originX:"center",originY:"bottom"}),o.group.push(a)),i.drawing.buffer.isDrawing=!0,"config"!=o.action){if(o.arrow){var l=new fabric.Group(o.group);return l.set({cfg:o,fill:o.color,action:o.action,selectable:!0,known:"change"==o.action}),"change"==o.action&&i.setup.fabric.setActiveObject(l),i.setup.fabric.add(l),l}return i.setup.fabric.add(s),s}for(t=0;t<o.group.length;t++)o.group[t].ignoreUndo=!0,i.setup.fabric.add(o.group[t]);return o}}},defaults:{position:"top-right",fileName:"amCharts",action:"download",overflow:!0,path:(e.path||"")+"plugins/export/",formats:{JPG:{mimeType:"image/jpg",extension:"jpg",capture:!0},PNG:{mimeType:"image/png",extension:"png",capture:!0},SVG:{mimeType:"text/xml",extension:"svg",capture:!0},PDF:{mimeType:"application/pdf",extension:"pdf",capture:!0},CSV:{mimeType:"text/plain",extension:"csv"},JSON:{mimeType:"text/plain",extension:"json"},XLSX:{mimeType:"application/octet-stream",extension:"xlsx"}},fabric:{backgroundColor:"#FFFFFF",removeImages:!0,forceRemoveImages:!1,selection:!1,loadTimeout:5e3,drawing:{enabled:!0,arrow:"end",lineCap:"butt",mode:"pencil",modes:["pencil","line","arrow"],color:"#000000",colors:["#000000","#FFFFFF","#FF0000","#00FF00","#0000FF"],shapes:["11.svg","14.svg","16.svg","17.svg","20.svg","27.svg"],width:1,fontSize:11,widths:[1,5,10,15],opacity:1,opacities:[1,.8,.6,.4,.2],menu:void 0,autoClose:!0},border:{fill:"",fillOpacity:0,stroke:"#000000",strokeWidth:1,strokeOpacity:1}},pdfMake:{images:{},pageOrientation:"portrait",pageMargins:40,pageOrigin:!0,pageSize:"A4",pageSizes:{"4A0":[4767.87,6740.79],"2A0":[3370.39,4767.87],A0:[2383.94,3370.39],A1:[1683.78,2383.94],A2:[1190.55,1683.78],A3:[841.89,1190.55],A4:[595.28,841.89],A5:[419.53,595.28],A6:[297.64,419.53],A7:[209.76,297.64],A8:[147.4,209.76],A9:[104.88,147.4],A10:[73.7,104.88],B0:[2834.65,4008.19],B1:[2004.09,2834.65],B2:[1417.32,2004.09],B3:[1000.63,1417.32],B4:[708.66,1000.63],B5:[498.9,708.66],B6:[354.33,498.9],B7:[249.45,354.33],B8:[175.75,249.45],B9:[124.72,175.75],B10:[87.87,124.72],C0:[2599.37,3676.54],C1:[1836.85,2599.37],C2:[1298.27,1836.85],C3:[918.43,1298.27],C4:[649.13,918.43],C5:[459.21,649.13],C6:[323.15,459.21],C7:[229.61,323.15],C8:[161.57,229.61],C9:[113.39,161.57],C10:[79.37,113.39],RA0:[2437.8,3458.27],RA1:[1729.13,2437.8],RA2:[1218.9,1729.13],RA3:[864.57,1218.9],RA4:[609.45,864.57],SRA0:[2551.18,3628.35],SRA1:[1814.17,2551.18],SRA2:[1275.59,1814.17],SRA3:[907.09,1275.59],SRA4:[637.8,907.09],EXECUTIVE:[521.86,756],FOLIO:[612,936],LEGAL:[612,1008],LETTER:[612,792],TABLOID:[792,1224]}},menu:void 0,divId:null,menuReviver:null,menuWalker:null,fallback:!0,keyListener:!0,fileListener:!0,compress:!0,debug:!1},listenersToRemove:[],i18l:function(e,t){var a=t||(i.setup.chart.language?i.setup.chart.language:"en");return(AmCharts.translations[i.name][a]||AmCharts.translations[i.name].en)[e]||e},download:function(e,t,a){if(window.saveAs&&i.setup.hasBlob)i.toBlob({data:e,type:t},function(e){saveAs(e,a)});else if(i.config.fallback&&"text/plain"==t){var r=document.createElement("div"),n=document.createElement("div"),o=document.createElement("textarea");n.innerHTML=i.i18l("fallback.save.text"),r.appendChild(n),r.appendChild(o),n.setAttribute("class","amcharts-export-fallback-message"),r.setAttribute("class","amcharts-export-fallback"),i.setup.chart.containerDiv.appendChild(r),o.setAttribute("readonly",""),o.value=e,o.focus(),o.select(),i.createMenu([{class:"export-main export-close",label:"Done",click:function(){i.createMenu(i.config.menu),i.isElement(i.setup.chart.containerDiv)&&i.setup.chart.containerDiv.removeChild(r)}}])}else{if(!i.config.fallback||"image"!=t.split("/")[0])throw new Error("Unable to create file. Ensure saveAs (FileSaver.js) is supported.");var r=document.createElement("div"),n=document.createElement("div"),s=i.toImage({data:e});n.innerHTML=i.i18l("fallback.save.image"),r.appendChild(n),r.appendChild(s),n.setAttribute("class","amcharts-export-fallback-message"),r.setAttribute("class","amcharts-export-fallback"),i.setup.chart.containerDiv.appendChild(r),i.createMenu([{class:"export-main export-close",label:"Done",click:function(){i.createMenu(i.config.menu),i.isElement(i.setup.chart.containerDiv)&&i.setup.chart.containerDiv.removeChild(r)}}])}return e},loadResource:function(e,t){function a(){i.handleLog(["amCharts[export]: Loading error on ",this.src||this.href].join(""))}function r(){if(t)for(n=0;n<t.length;n++)i.loadResource(t[n])}var n,o,s,l=-1!=e.indexOf("//")?e:[i.libs.path,e].join("");for(-1!=e.indexOf(".js")?((s=document.createElement("script")).setAttribute("type","text/javascript"),s.setAttribute("src",l),i.libs.async&&s.setAttribute("async","")):-1!=e.indexOf(".css")&&((s=document.createElement("link")).setAttribute("type","text/css"),s.setAttribute("rel","stylesheet"),s.setAttribute("href",l)),n=0;n<document.head.childNodes.length;n++)if(p=document.head.childNodes[n],c=!!p&&(p.src||p.href),!!p&&p.tagName,p&&c&&-1!=c.indexOf(e)){i.libs.reload&&document.head.removeChild(p),o=!0;break}for(n in i.libs.namespaces){var d=i.libs.namespaces[n],c=e.toLowerCase(),p=n.toLowerCase();if(-1!=c.indexOf(p)&&void 0!==window[d]){o=!0;break}}o&&!i.libs.reload||(s.addEventListener("load",r),i.addListenerToRemove("load",s,r),s.addEventListener("error",a),i.addListenerToRemove("error",s,a),document.head.appendChild(s))},addListenerToRemove:function(e,t,a){i.listenersToRemove.push({node:t,method:a,event:e})},loadDependencies:function(){var e,t;if(i.libs.autoLoad)for(e=0;e<i.libs.resources.length;e++)if(i.libs.resources[e]instanceof Object)for(t in i.libs.resources[e])i.loadResource(t,i.libs.resources[e][t]);else i.loadResource(i.libs.resources[e])},pxToNumber:function(e,t){if(e||!t)return Number(String(e).replace("px",""))||0},numberToPx:function(e){return String(e)+"px"},cloneObject:function(e){var t,a,r,n,o;t=Array.isArray(e)?[]:{};for(r in e)n="object"==typeof(a=e[r]),o=a instanceof Date,t[r]=n&&!o?i.cloneObject(a):a;return t},deepMerge:function(e,t,a){var r,n,o=t instanceof Array?"array":"object";if(!(e instanceof Object||e instanceof Array))return e;for(r in t)"array"==o&&isNaN(r)||(n=t[r],(e&&void 0==e[r]||a)&&(n instanceof Array?e[r]=new Array:n instanceof Function?e[r]=function(){}:n instanceof Date?e[r]=new Date:n instanceof Object?e[r]=new Object:n instanceof Number?e[r]=new Number:n instanceof String&&(e[r]=new String)),(n instanceof Object||n instanceof Array)&&!(n instanceof Function||n instanceof Date||i.isElement(n))&&"chart"!=r&&"scope"!=r?i.deepMerge(e[r],n,a):e instanceof Array&&!a?e.push(n):e&&(e[r]=n));return e},isElement:function(e){return e instanceof Object&&e&&1===e.nodeType},isHashbanged:function(e){var t=String(e).replace(/\"/g,"");return"url"==t.slice(0,3)&&t.slice(t.indexOf("#")+1,t.length-1)},isPressed:function(e){return"mousemove"==e.type&&1===e.which||("touchmove"==e.type||1===e.buttons||1===e.button||1===e.which?i.drawing.buffer.isPressed=!0:i.drawing.buffer.isPressed=!1),i.drawing.buffer.isPressed},removeImage:function(e){if(e){if(i.config.fabric.forceRemoveImages)return!0;if(i.config.fabric.removeImages&&i.isTainted(e))return!0;if(i.setup.isIE&&(10==i.setup.IEversion||11==i.setup.IEversion)&&-1!=e.toLowerCase().indexOf(".svg"))return!0}return!1},isTainted:function(e){var t=String(window.location.origin||window.location.protocol+"//"+window.location.hostname+(window.location.port?":"+window.location.port:""));if(e){if(-1!=t.indexOf(":\\")||-1!=e.indexOf(":\\")||-1!=t.indexOf("file://")||-1!=e.indexOf("file://"))return!0;if(-1!=e.indexOf("//")&&-1==e.indexOf(t.replace(/.*:/,"")))return!0}return!1},isSupported:function(){return!!i.config.enabled&&!(i.setup.isIE&&i.setup.IEversion<=9&&(!Array.prototype.indexOf||!document.head||!1===i.config.fallback))},getAngle:function(e,t,a,i){var r=a-e,n=i-t;return 180*(0==r?0==n?0:n>0?Math.PI/2:3*Math.PI/2:0==n?r>0?0:Math.PI:r<0?Math.atan(n/r)+Math.PI:n<0?Math.atan(n/r)+2*Math.PI:Math.atan(n/r))/Math.PI},gatherAttribute:function(e,t,a,r){var n,r=r||0,a=a||3;return e&&!(n=e.getAttribute(t))&&r<a?i.gatherAttribute(e.parentNode,t,a,r+1):n},gatherClassName:function(e,t,a,r){var n,r=r||0,a=a||3;if(i.isElement(e)){if(!(n=-1!=(e.getAttribute("class")||"").split(" ").indexOf(t))&&r<a)return i.gatherClassName(e.parentNode,t,a,r+1);n&&(n=e)}return n},gatherElements:function(e,t,a){var r,n;for(r=0;r<e.children.length;r++){var o=e.children[r];if("clipPath"==o.tagName){var s={},l=fabric.parseTransformAttribute(i.gatherAttribute(o,"transform"));for(n=0;n<o.childNodes.length;n++)o.childNodes[n].setAttribute("fill","transparent"),s={x:i.pxToNumber(o.childNodes[n].getAttribute("x")),y:i.pxToNumber(o.childNodes[n].getAttribute("y")),width:i.pxToNumber(o.childNodes[n].getAttribute("width")),height:i.pxToNumber(o.childNodes[n].getAttribute("height"))};e.clippings[o.id]={svg:o,bbox:s,transform:l}}else if("pattern"==o.tagName){var d={node:o,source:o.getAttribute("xlink:href"),width:Number(o.getAttribute("width")),height:Number(o.getAttribute("height")),repeat:"repeat",offsetX:0,offsetY:0};for(n=0;n<o.childNodes.length;n++)"rect"==o.childNodes[n].tagName?d.fill=o.childNodes[n].getAttribute("fill"):"image"==o.childNodes[n].tagName&&(c=fabric.parseAttributes(o.childNodes[n],fabric.SHARED_ATTRIBUTES)).transformMatrix&&(d.offsetX=c.transformMatrix[4],d.offsetY=c.transformMatrix[5]);i.removeImage(d.source)?e.patterns[o.id]=d.fill?d.fill:"transparent":e.patterns[d.node.id]=d}else if("image"==o.tagName)a.included++,fabric.Image.fromURL(o.getAttribute("xlink:href"),function(e){a.loaded++});else{var c=["fill","stroke"];for(n=0;n<c.length;n++){var p=c[n],f=o.getAttribute(p),u=i.getRGBA(f),g=i.isHashbanged(f);!f||u||g||(o.setAttribute(p,"none"),o.setAttribute(p+"-opacity","0"))}}}return e},getRGBA:function(e,t){return!("none"==e||"transparent"==e||i.isHashbanged(e)||!(e=new fabric.Color(e))._source)&&(t?e:e.getSource())},gatherPosition:function(e,t){var a,r=i.drawing.buffer.position,n=fabric.util.invertTransform(i.setup.fabric.viewportTransform);return"touchmove"==e.type&&("touches"in e?e=e.touches[0]:"changedTouches"in e&&(e=e.changedTouches[0])),a=fabric.util.transformPoint(i.setup.fabric.getPointer(e,!0),n),1==t&&(r.x1=a.x,r.y1=a.y),r.x2=a.x,r.y2=a.y,r.xD=r.x1-r.x2<0?-1*(r.x1-r.x2):r.x1-r.x2,r.yD=r.y1-r.y2<0?-1*(r.y1-r.y2):r.y1-r.y2,r},modifyFabric:function(){fabric.ElementsParser.prototype.resolveGradient=function(e,t){var a=e.get(t);if(/^url\(/.test(a)){var r=a.slice(a.indexOf("#")+1,a.length-1);if(fabric.gradientDefs[this.svgUid][r]){var n=fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][r],e);n.coords.y1&&"pie"!=i.setup.chart.type&&(n.coords.y2=-1*n.coords.y1,n.coords.y1=0),e.set(t,n)}}},fabric.Text.fromElement=function(e,t){if(!e)return null;var a=fabric.parseAttributes(e,fabric.Text.ATTRIBUTE_NAMES);(t=fabric.util.object.extend(t?fabric.util.object.clone(t):{},a)).top=t.top||0,t.left=t.left||0,"dx"in a&&(t.left+=a.dx),"dy"in a&&(t.top+=a.dy),"fontSize"in t||(t.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE),t.originX||(t.originX="left");var i="",r=[];if("textContent"in e)if(e.childNodes)for(var n=0;n<e.childNodes.length;n++)r.push(e.childNodes[n].textContent);else r.push(e.textContent);else"firstChild"in e&&null!==e.firstChild&&"data"in e.firstChild&&null!==e.firstChild.data&&r.push(e.firstChild.data);i=r.join("\n");var o=new fabric.Text(i,t),s=0;return"left"===o.originX&&(s=o.getWidth()/2),"right"===o.originX&&(s=-o.getWidth()/2),r.length>1?o.set({left:o.getLeft()+s,top:o.getTop()+o.fontSize*(r.length-1)*(.18+o._fontSizeFraction),textAlign:t.originX,lineHeight:r.length>1?.965:1.16}):o.set({left:o.getLeft()+s,top:o.getTop()-o.getHeight()/2+o.fontSize*(.18+o._fontSizeFraction)}),o}},capture:function(e,t){var a,r=i.deepMerge(i.deepMerge({},i.config.fabric),e||{}),n=[],o={x:0,y:0,pX:0,pY:0,lX:0,lY:0,width:i.setup.chart.divRealWidth,height:i.setup.chart.divRealHeight},s={loaded:0,included:0},l={items:[],width:0,height:0,maxWidth:0,maxHeight:0};if(!i.handleNamespace("fabric",{scope:this,cb:i.capture,args:arguments}))return!1;i.modifyFabric(),i.handleCallback(r.beforeCapture,r);var d=i.setup.chart.containerDiv.getElementsByTagName("svg");for(a=0;a<d.length;a++)(p={svg:d[a],parent:d[a].parentNode,children:d[a].getElementsByTagName("*"),offset:{x:0,y:0},patterns:{},clippings:{},has:{legend:!1,panel:!1,scrollbar:!1}}).has.legend=i.gatherClassName(p.parent,i.setup.chart.classNamePrefix+"-legend-div",1),p.has.panel=i.gatherClassName(p.parent,i.setup.chart.classNamePrefix+"-stock-panel-div"),p.has.scrollbar=i.gatherClassName(p.parent,i.setup.chart.classNamePrefix+"-scrollbar-chart-div"),p=i.gatherElements(p,r,s),n.push(p);if(i.config.legend){if("stock"==i.setup.chart.type)for(a=0;a<i.setup.chart.panels.length;a++)i.setup.chart.panels[a].stockLegend&&i.setup.chart.panels[a].stockLegend.divId&&l.items.push(i.setup.chart.panels[a].stockLegend);else i.setup.chart.legend&&i.setup.chart.legend.divId&&l.items.push(i.setup.chart.legend);for(a=0;a<l.items.length;a++){var c=l.items[a],p={svg:c.container.container,parent:c.container.container.parentNode,children:c.container.container.getElementsByTagName("*"),offset:{x:0,y:0},legend:{id:a,type:-1!=["top","left"].indexOf(i.config.legend.position)?"unshift":"push",position:i.config.legend.position,width:i.config.legend.width?i.config.legend.width:c.container.div.offsetWidth,height:i.config.legend.height?i.config.legend.height:c.container.div.offsetHeight},patterns:{},clippings:{},has:{legend:!1,panel:!1,scrollbar:!1}};l.width+=p.legend.width,l.height+=p.legend.height,l.maxWidth=p.legend.width>l.maxWidth?p.legend.width:l.maxWidth,l.maxHeight=p.legend.height>l.maxHeight?p.legend.height:l.maxHeight,p=i.gatherElements(p,r,s),n[p.legend.type](p)}-1!=["top","bottom"].indexOf(i.config.legend.position)?(o.width=l.maxWidth>o.width?l.maxWidth:o.width,o.height+=l.height):-1!=["left","right"].indexOf(i.config.legend.position)?(o.width+=l.maxWidth,o.height=l.height>o.height?l.height:o.height):(o.height+=l.height,o.width+=l.maxWidth)}if(i.drawing.enabled=r.drawing.enabled="draw"==r.action,i.drawing.buffer.enabled=i.drawing.enabled,i.setup.wrapper=document.createElement("div"),i.setup.wrapper.setAttribute("class",i.setup.chart.classNamePrefix+"-export-canvas"),i.setup.chart.containerDiv.appendChild(i.setup.wrapper),"stock"==i.setup.chart.type){var f={top:0,right:0,bottom:0,left:0};i.setup.chart.leftContainer&&(o.width-=i.setup.chart.leftContainer.offsetWidth,f.left=i.setup.chart.leftContainer.offsetWidth+2*i.setup.chart.panelsSettings.panelSpacing),i.setup.chart.rightContainer&&(o.width-=i.setup.chart.rightContainer.offsetWidth,f.right=i.setup.chart.rightContainer.offsetWidth+2*i.setup.chart.panelsSettings.panelSpacing),i.setup.chart.periodSelector&&-1!=["top","bottom"].indexOf(i.setup.chart.periodSelector.position)&&(o.height-=i.setup.chart.periodSelector.offsetHeight+i.setup.chart.panelsSettings.panelSpacing,f[i.setup.chart.periodSelector.position]+=i.setup.chart.periodSelector.offsetHeight+i.setup.chart.panelsSettings.panelSpacing),i.setup.chart.dataSetSelector&&-1!=["top","bottom"].indexOf(i.setup.chart.dataSetSelector.position)&&(o.height-=i.setup.chart.dataSetSelector.offsetHeight,f[i.setup.chart.dataSetSelector.position]+=i.setup.chart.dataSetSelector.offsetHeight),i.setup.wrapper.style.paddingTop=i.numberToPx(f.top),i.setup.wrapper.style.paddingRight=i.numberToPx(f.right),i.setup.wrapper.style.paddingBottom=i.numberToPx(f.bottom),i.setup.wrapper.style.paddingLeft=i.numberToPx(f.left)}i.setup.canvas=document.createElement("canvas"),i.setup.wrapper.appendChild(i.setup.canvas);var u=i.removeFunctionsFromObject(i.deepMerge({width:o.width,height:o.height,isDrawingMode:!0},r));for(i.setup.fabric=new fabric.Canvas(i.setup.canvas,u),i.deepMerge(i.setup.fabric,r),i.deepMerge(i.setup.fabric.freeDrawingBrush,r.drawing),i.deepMerge(i.drawing,r.drawing),i.drawing.handler.change(r.drawing),i.setup.fabric.on("mouse:down",function(e){i.gatherPosition(e.e,1);i.drawing.buffer.pressedTS=Number(new Date),i.isPressed(e.e),i.drawing.buffer.isDrawing=!1,i.drawing.buffer.isDrawingTimer=setTimeout(function(){i.drawing.buffer.isSelected||(i.drawing.buffer.isDrawing=!0)},200)}),i.setup.fabric.on("mouse:move",function(e){var t=i.gatherPosition(e.e,2);if(i.isPressed(e.e),i.drawing.buffer.isPressed&&!i.drawing.buffer.isSelected&&(i.drawing.buffer.isDrawing=!0,!i.drawing.buffer.line&&"pencil"!=i.drawing.mode&&(t.xD>5||t.yD>5)&&(i.setup.fabric.isDrawingMode=!1,i.setup.fabric._isCurrentlyDrawing=!1,i.drawing.buffer.ignoreUndoOnMouseUp=!0,i.setup.fabric.freeDrawingBrush.onMouseUp(),i.setup.fabric.remove(i.setup.fabric._objects.pop()),i.drawing.buffer.line=i.drawing.handler.line({x1:t.x1,y1:t.y1,x2:t.x2,y2:t.y2,arrow:"line"!=i.drawing.mode&&i.drawing.arrow,action:"config"}))),i.drawing.buffer.isSelected&&(i.setup.fabric.isDrawingMode=!1),i.drawing.buffer.line){var r,n,o,s=i.drawing.buffer.line;for(s.x2=t.x2,s.y2=t.y2,a=0;a<s.group.length;a++)(r=s.group[a])instanceof fabric.Line?r.set({x2:s.x2,y2:s.y2}):r instanceof fabric.Triangle&&(s.angle=i.getAngle(s.x1,s.y1,s.x2,s.y2)+90,"start"==s.arrow?(n=s.y1+s.width/2,o=s.x1+s.width/2):"middle"==s.arrow?(n=s.y2+s.width/2-(s.y2-s.y1)/2,o=s.x2+s.width/2-(s.x2-s.x1)/2):(n=s.y2+s.width/2,o=s.x2+s.width/2),r.set({top:n,left:o,angle:s.angle}));i.setup.fabric.renderAll()}}),i.setup.fabric.on("mouse:up",function(e){if(!i.drawing.buffer.isDrawing){var t=i.setup.fabric.findTarget(e.e);t&&t.selectable&&i.setup.fabric.setActiveObject(t)}if(i.drawing.buffer.line){for(a=0;a<i.drawing.buffer.line.group.length;a++)i.drawing.buffer.line.group[a].remove();delete i.drawing.buffer.line.action,delete i.drawing.buffer.line.group,i.drawing.handler.line(i.drawing.buffer.line)}i.drawing.buffer.line=!1,i.drawing.buffer.hasLine=!1,i.drawing.buffer.isPressed=!1,clearTimeout(i.drawing.buffer.isDrawingTimer),i.drawing.buffer.isDrawing=!1}),i.setup.fabric.on("object:selected",function(e){i.drawing.buffer.isSelected=!0,i.drawing.buffer.target=e.target,i.setup.fabric.isDrawingMode=!1}),i.setup.fabric.on("selection:cleared",function(e){i.drawing.buffer.target=!1,i.drawing.buffer.isSelected&&(i.setup.fabric._isCurrentlyDrawing=!1),i.drawing.buffer.isSelected=!1,i.setup.fabric.isDrawingMode=!0}),i.setup.fabric.on("path:created",function(e){var t=e.path;if(!i.drawing.buffer.isDrawing||i.drawing.buffer.hasLine)return i.setup.fabric.remove(t),void i.setup.fabric.renderAll()}),i.setup.fabric.on("object:added",function(e){var t=e.target,a=i.deepMerge(t.saveState()._stateProperties,{cfg:{color:i.drawing.color,width:i.drawing.width,opacity:i.drawing.opacity,fontSize:i.drawing.fontSize}});a=JSON.stringify(a),t.recentState=a,!i.drawing.buffer.ignoreUndoOnMouseUp&&i.drawing.buffer.isDrawing?(!t.selectable||t.known||t.ignoreUndo||(t.isAnnotation=!0,i.drawing.undos.push({action:"added",target:t,state:a}),i.drawing.redos=[]),t.known=!0,i.setup.fabric.isDrawingMode=!0):i.drawing.buffer.ignoreUndoOnMouseUp=!1}),i.setup.fabric.on("object:modified",function(e){var t=e.target,a=JSON.parse(t.recentState),r=i.deepMerge(t.saveState()._stateProperties,{cfg:a.cfg});r=JSON.stringify(r),t.recentState=r,i.drawing.undos.push({action:"modified",target:t,state:r}),i.drawing.redos=[]}),i.setup.fabric.on("text:changed",function(e){var t=e.target;clearTimeout(t.timer),t.timer=setTimeout(function(){var e=JSON.stringify(t.saveState()._stateProperties);t.recentState=e,i.drawing.redos=[],i.drawing.undos.push({action:"modified",target:t,state:e})},250)}),i.drawing.enabled?(i.setup.wrapper.setAttribute("class",i.setup.chart.classNamePrefix+"-export-canvas active"),i.setup.wrapper.style.backgroundColor=r.backgroundColor,i.setup.wrapper.style.display="block"):(i.setup.wrapper.setAttribute("class",i.setup.chart.classNamePrefix+"-export-canvas"),i.setup.wrapper.style.display="none"),a=0;a<n.length;a++){p=n[a];"stock"==i.setup.chart.type&&i.setup.chart.legendSettings.position?-1!=["top","bottom"].indexOf(i.setup.chart.legendSettings.position)?p.parent.style.top&&p.parent.style.left?(p.offset.y=i.pxToNumber(p.parent.style.top),p.offset.x=i.pxToNumber(p.parent.style.left)):(p.offset.x=o.x,p.offset.y=o.y,o.y+=i.pxToNumber(p.parent.style.height),p.has.panel?(o.pY=i.pxToNumber(p.has.panel.style.marginTop),p.offset.y+=o.pY):p.has.scrollbar&&(p.offset.y+=o.pY)):-1!=["left","right"].indexOf(i.setup.chart.legendSettings.position)&&(p.offset.y=i.pxToNumber(p.parent.style.top)+o.pY,p.offset.x=i.pxToNumber(p.parent.style.left)+o.pX,p.has.legend?o.pY+=i.pxToNumber(p.has.panel.style.height)+i.setup.chart.panelsSettings.panelSpacing:p.has.scrollbar&&(p.offset.y-=i.setup.chart.panelsSettings.panelSpacing)):("absolute"==p.parent.style.position?(p.offset.absolute=!0,p.offset.top=i.pxToNumber(p.parent.style.top),p.offset.right=i.pxToNumber(p.parent.style.right,!0),p.offset.bottom=i.pxToNumber(p.parent.style.bottom,!0),p.offset.left=i.pxToNumber(p.parent.style.left),p.offset.width=i.pxToNumber(p.parent.style.width),p.offset.height=i.pxToNumber(p.parent.style.height)):p.parent.style.top&&p.parent.style.left?(p.offset.y=i.pxToNumber(p.parent.style.top),p.offset.x=i.pxToNumber(p.parent.style.left)):p.legend?("left"==p.legend.position?o.x=l.maxWidth:"right"==p.legend.position?p.offset.x=o.width-l.maxWidth:"top"==p.legend.position?o.y+=p.legend.height:"bottom"==p.legend.position&&(p.offset.y=o.height-l.height),p.offset.y+=o.lY,o.lY+=p.legend.height):(p.offset.x=o.x,p.offset.y=o.y+o.pY,o.y+=i.pxToNumber(p.parent.style.height)),p.has.legend&&p.has.panel&&p.has.panel.style.marginTop?(o.y+=i.pxToNumber(p.has.panel.style.marginTop),p.offset.y+=i.pxToNumber(p.has.panel.style.marginTop)):i.setup.chart.legend&&-1!=["left","right"].indexOf(i.setup.chart.legend.position)&&(p.offset.y=i.pxToNumber(p.parent.style.top),p.offset.x=i.pxToNumber(p.parent.style.left))),fabric.parseSVGDocument(p.svg,function(e){return function(a,l){var d,c=fabric.util.groupSVGElements(a,l),p=[],f={selectable:!1,isCoreElement:!0};for(e.offset.absolute?(void 0!==e.offset.bottom?f.top=o.height-e.offset.height-e.offset.bottom:f.top=e.offset.top,void 0!==e.offset.right?f.left=o.width-e.offset.width-e.offset.right:f.left=e.offset.left):(f.top=e.offset.y,f.left=e.offset.x),d=0;d<c.paths.length;d++){var u=null;if(c.paths[d]){if(i.removeImage(c.paths[d]["xlink:href"]))continue;if(c.paths[d].fill instanceof Object)"radial"==c.paths[d].fill.type&&-1==["pie","gauge"].indexOf(i.setup.chart.type)&&(c.paths[d].fill.coords.r2=-1*c.paths[d].fill.coords.r1,c.paths[d].fill.coords.r1=0,c.paths[d].set({opacity:c.paths[d].fillOpacity}));else if((u=i.isHashbanged(c.paths[d].fill))&&e.patterns&&e.patterns[u]){var g=e.patterns[u];s.included++,fabric.Image.fromURL(g.source,function(e,t){return function(a){s.loaded++,a.set({top:e.offsetY,left:e.offsetX,width:e.width,height:e.height}),i.setup.fabric._isRetinaScaling()&&a.set({top:e.offsetY/2,left:e.offsetX/2,scaleX:.5,scaleY:.5});var r=new fabric.StaticCanvas(void 0,{backgroundColor:e.fill,width:a.getWidth(),height:a.getHeight()});r.add(a);var n=new fabric.Pattern({source:r.getElement(),offsetX:c.paths[t].width/2,offsetY:c.paths[t].height/2,repeat:"repeat"});c.paths[t].set({fill:n,opacity:c.paths[t].fillOpacity})}}(g,d))}(u=i.isHashbanged(c.paths[d].clipPath))&&e.clippings&&e.clippings[u]&&(!function(t,a){var i=c.paths[t].toSVG;c.paths[t].toSVG=function(t){return i.apply(this,[function(i){return t(i,e.clippings[a])}])}}(d,u),c.paths[d].set({clipTo:function(t,a){return function(r){var n=e.clippings[a],o=this.transformMatrix||[1,0,0,1,0,0],s={top:n.bbox.y,left:n.bbox.x,width:n.bbox.width,height:n.bbox.height};"map"==i.setup.chart.type&&(s.top+=n.transform[5],s.left+=n.transform[4]),n.bbox.x&&o[4]&&n.bbox.y&&o[5]&&(s.top-=o[5],s.left-=o[4]),void 0!==i.setup.chart.smoothCustomBullets&&this.className==i.setup.chart.classNamePrefix+"-graph-bullet"&&"image"==c.paths[t].svg.tagName?(radius=n.svg.firstChild.rx.baseVal.value/2+2,r.beginPath(),r.moveTo(s.left+radius,s.top),r.lineTo(s.left+s.width-radius,s.top),r.quadraticCurveTo(s.left+s.width,s.top,s.left+s.width,s.top+radius),r.lineTo(s.left+s.width,s.top+s.height-radius),r.quadraticCurveTo(s.left+s.width,s.top+s.height,s.left+s.width-radius,s.top+s.height),r.lineTo(s.left+radius,s.top+s.height),r.quadraticCurveTo(s.left,s.top+s.height,s.left,s.top+s.height-radius),r.lineTo(s.left,s.top+radius),r.quadraticCurveTo(s.left,s.top,s.left+radius,s.top),r.closePath()):r.rect(s.left,s.top,s.width,s.height)}}(d,u)}))}p.push(c.paths[d])}if(c.paths=p,f.top+=.5,f.left+=.5,c.set(f),i.setup.fabric.add(c),e.svg.parentNode&&e.svg.parentNode.getElementsByTagName){var h=e.svg.parentNode.getElementsByClassName(i.setup.chart.classNamePrefix+"-balloon-div");for(d=0;d<h.length;d++)if(r.balloonFunction instanceof Function)r.balloonFunction.apply(i,[h[d],e]);else{var m=h[d],b=fabric.parseStyleAttribute(m),v=fabric.parseStyleAttribute(m.childNodes[0]),w=new fabric.Text(m.innerText||m.textContent||m.innerHTML,{selectable:!1,top:i.pxToNumber(b.top)+e.offset.y,left:i.pxToNumber(b.left)+e.offset.x,fill:v.color,fontSize:i.pxToNumber(v.fontSize||v["font-size"]),fontFamily:v.fontFamily||v["font-family"],textAlign:v["text-align"],isCoreElement:!0});i.setup.fabric.add(w)}}if(e.svg.nextSibling&&"A"==e.svg.nextSibling.tagName){var m=e.svg.nextSibling,b=fabric.parseStyleAttribute(m),w=new fabric.Text(m.innerText||m.textContent||m.innerHTML,{selectable:!1,top:i.pxToNumber(b.top)+e.offset.y,left:i.pxToNumber(b.left)+e.offset.x,fill:b.color,fontSize:i.pxToNumber(b.fontSize||b["font-size"]),fontFamily:b.fontFamily||b["font-family"],opacity:b.opacity,isCoreElement:!0});e.has.scrollbar||i.setup.fabric.add(w)}if(n.pop(),!n.length)var y=Number(new Date),x=setInterval(function(){var e=Number(new Date);(s.loaded==s.included||e-y>i.config.fabric.loadTimeout)&&(clearTimeout(x),i.handleBorder(r),i.handleCallback(r.afterCapture,r),i.setup.fabric.renderAll(),i.handleCallback(t,r))},AmCharts.updateRate)}}(p),function(e,t){var a,n=i.gatherAttribute(e,"class"),o=i.gatherAttribute(e,"visibility"),s=i.gatherAttribute(e,"clip-path");t.className=String(n),t.classList=String(n).split(" "),t.clipPath=s,t.svg=e;var l=["fill","stroke"];for(a=0;a<l.length;a++){var d=l[a],c=String(e.getAttribute(d)||"none"),p=Number(e.getAttribute(d+"-opacity")||"1"),f=i.getRGBA(c);"hidden"==o&&(t.opacity=0,p=0),f&&(f.pop(),f.push(p),t[d]="rgba("+f.join()+")",t[d+i.capitalize("opacity")]=p)}i.handleCallback(r.reviver,t,e)})}},toCanvas:function(e,t){var a=i.deepMerge({},e||{}),r=i.setup.canvas;return i.handleCallback(t,r,a),r},toImage:function(e,t){var a=i.deepMerge({format:"png",quality:1,multiplier:i.config.multiplier},e||{}),r=a.data,n=document.createElement("img");return!!i.handleNamespace("fabric",{scope:this,cb:i.toImage,args:arguments})&&(a.data||(r=a.lossless||"svg"==a.format?i.toSVG(i.deepMerge(a,{getBase64:!0})):i.setup.fabric.toDataURL(a)),n.setAttribute("src",r),i.handleCallback(t,n,a),n)},toBlob:function(e,t){var a,r=i.deepMerge({data:"empty",type:"text/plain"},e||{}),n=/^data:.+;base64,(.*)$/.exec(r.data);return n&&(r.data=n[0],r.type=r.data.slice(5,r.data.indexOf(",")-7),r.data=i.toByteArray({data:r.data.slice(r.data.indexOf(",")+1,r.data.length)})),a=r.getByteArray?r.data:new Blob([r.data],{type:r.type}),i.handleCallback(t,a,r),a},toJPG:function(e,t){var a=i.deepMerge({format:"jpeg",quality:1,multiplier:i.config.multiplier},e||{});a.format=a.format.toLowerCase();var r;return/iP(hone|od|ad)/.test(navigator.platform)&&(a.multiplier=1),!!i.handleNamespace("fabric",{scope:this,cb:i.toJPG,args:arguments})&&(r=i.setup.fabric.toDataURL(a),i.handleCallback(t,r,a),r)},toPNG:function(e,t){var a,r=i.deepMerge({format:"png",quality:1,multiplier:i.config.multiplier},e||{});return/iP(hone|od|ad)/.test(navigator.platform)&&(r.multiplier=1),!!i.handleNamespace("fabric",{scope:this,cb:i.toPNG,args:arguments})&&(a=i.setup.fabric.toDataURL(r),i.handleCallback(t,a,r),a)},toSVG:function(e,t){var a,r=[],n=[],o=i.deepMerge({compress:i.config.compress,reviver:function(e,t){var a=new RegExp(/\bstyle=(['"])(.*?)\1/).exec(e)[0].slice(7,-1),o=a.split(";"),s=[];for(i1=0;i1<o.length;i1++)if(o[i1]){var l=o[i1].replace(/\s/g,"").split(":"),d=l[0],c=l[1];if(-1!=["fill","stroke"].indexOf(d))if(c=i.getRGBA(c,!0)){var p="#"+c.toHex(),f=c._source[3];s.push([d,p].join(":")),s.push([d+"-opacity",f].join(":"))}else s.push(o[i1]);else"opactiy"!=d&&s.push(o[i1])}if(e=e.replace(a,s.join(";")),t&&t.svg){var u=t.svg.id,g=2,h=e.slice(-g);"/>"!=h&&(g=3,h=e.slice(-g));var m=e.slice(0,e.length-g),b=' clip-path="url(#'+u+')" ',v=i.gatherAttribute(t.svg,"class");if(v=v?v.split(" "):[],e=-1!=v.indexOf(i.setup.chart.classNamePrefix+"-graph-line")?m+b+h:"<g "+b+">"+e+"</g>",-1==n.indexOf(u)){var w=(new XMLSerializer).serializeToString(t.svg);r.push(w),n.push(u)}}return e}},e||{});if(!i.handleNamespace("fabric",{scope:this,cb:i.toSVG,args:arguments}))return!1;if(a=i.setup.fabric.toSVG(o,o.reviver),r.length){var s=a.slice(0,a.length-6),l=a.slice(-6);a=s+r.join("")+l}return o.compress&&(a=a.replace(/[\t\r\n]+/g,"")),o.getBase64&&(a="data:image/svg+xml;base64,"+btoa(a)),i.handleCallback(t,a,o),a},toPDF:function(e,t){var a,r=i.deepMerge(i.deepMerge({multiplier:i.config.multiplier||2,pageOrigin:void 0===i.config.pageOrigin},i.config.pdfMake),e||{},!0);if(/iP(hone|od|ad)/.test(navigator.platform)&&(r.multiplier=1),!i.handleNamespace("pdfMake",{scope:this,cb:i.toPDF,args:arguments}))return!1;if(r.images.reference=i.toPNG(r),!r.content){var n=[],o=function(e,t){var a=i.defaults.pdfMake.pageSizes[String(e).toUpperCase()].slice();if(!a)throw new Error('The given pageSize "'+e+'" does not exist!');return"landscape"==t&&a.reverse(),a}(r.pageSize,r.pageOrientation),s=function(e){if("number"==typeof e||e instanceof Number)e={left:e,right:e,top:e,bottom:e};else if(e instanceof Array)if(2===e.length)e={left:e[0],top:e[1],right:e[0],bottom:e[1]};else{if(4!==e.length)throw"Invalid pageMargins definition";e={left:e[0],top:e[1],right:e[2],bottom:e[3]}}else e={left:i.defaults.pdfMake.pageMargins,top:i.defaults.pdfMake.pageMargins,right:i.defaults.pdfMake.pageMargins,bottom:i.defaults.pdfMake.pageMargins};return e}(r.pageMargins);o[0]-=s.left+s.right,o[1]-=s.top+s.bottom,r.pageOrigin&&(n.push(i.i18l("label.saved.from")),n.push(window.location.href),o[1]-=28.128),n.push({image:"reference",fit:o}),r.content=n}return a=new pdfMake.createPdf(r),t&&a.getDataUrl(function(e){return function(t){e.apply(i,arguments)}}(t)),a},toPRINT:function(e,t){var a,r=i.deepMerge({delay:1,lossless:!1},e||{}),n=i.toImage(r),o=[],s=document.body.childNodes,l=document.documentElement.scrollTop||document.body.scrollTop;for(n.setAttribute("style","width: 100%; max-height: 100%;"),a=0;a<s.length;a++)i.isElement(s[a])&&(o[a]=s[a].style.display,s[a].style.display="none");return document.body.appendChild(n),r.delay*=1e3,/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream&&r.delay<1e3&&(r.delay=1e3),setTimeout(function(){window.print(),setTimeout(function(){for(a=0;a<s.length;a++)i.isElement(s[a])&&(s[a].style.display=o[a]);document.body.removeChild(n),document.documentElement.scrollTop=document.body.scrollTop=l,i.handleCallback(t,n,r)},r.delay)},r.delay),n},toJSON:function(e,t){var a=i.deepMerge({dateFormat:i.config.dateFormat||"dateObject"},e||{},!0),r={};return!!i.handleNamespace("JSON",{scope:this,cb:i.toJSON,args:arguments})&&(a.data=void 0!==a.data?a.data:i.getChartData(a),r=JSON.stringify(a.data,void 0,"\t"),i.handleCallback(t,r,a),r)},toCSV:function(e,t){var a,r=i.deepMerge({delimiter:",",quotes:!0,escape:!0,withHeader:!0},e||{},!0),n=[],o="";n=i.toArray(r);for(a in n)isNaN(a)||(o+=n[a].join(r.delimiter)+"\n");return i.handleCallback(t,o,r),o},toXLSX:function(e,t){function a(e,t){return t&&(e+=1462),(Date.parse(e)-60*e.getTimezoneOffset()*1e3-new Date(Date.UTC(1899,11,30)))/864e5}var r=i.deepMerge({name:"amCharts",dateFormat:i.config.dateFormat||"dateObject",withHeader:!0,stringify:!1},e||{},!0),n=[],o="",s={SheetNames:[],Sheets:{}};return!!i.handleNamespace("XLSX",{scope:this,cb:i.toXLSX,args:arguments})&&(n=i.toArray(r),s.SheetNames.push(r.name),s.Sheets[r.name]=function(e,t){for(var i={},r={s:{c:1e7,r:1e7},e:{c:0,r:0}},n=0;n!=e.length;++n)for(var o=0;o!=e[n].length;++o){r.s.r>n&&(r.s.r=n),r.s.c>o&&(r.s.c=o),r.e.r<n&&(r.e.r=n),r.e.c<o&&(r.e.c=o);var s={v:e[n][o]};if(null!=s.v){var l=XLSX.utils.encode_cell({c:o,r:n});"number"==typeof s.v?s.t="n":"boolean"==typeof s.v?s.t="b":s.v instanceof Date?(s.t="n",s.z=XLSX.SSF._table[14],s.v=a(s.v)):s.v instanceof Object?(s.t="s",s.v=JSON.stringify(s.v)):s.t="s",i[l]=s}}return r.s.c<1e7&&(i["!ref"]=XLSX.utils.encode_range(r)),i}(n),o=XLSX.write(s,{bookType:"xlsx",bookSST:!0,type:"base64"}),o="data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,"+o,i.handleCallback(t,o,r),o)},toArray:function(e,t){function a(e,t){var a=t.exportFields||Object.keys(t.dataFieldsMap);for(p=0;p<a.length;p++){var r=a[p],n=t.dataFieldsTitlesMap[r];l.push(n)}return c?i.handleCallback(c,e,t):e}function r(e){return"string"==typeof e&&(o.escape&&(e=e.replace('"','""')),o.quotes&&(e=['"',e,'"'].join(""))),e}var n,o=i.deepMerge({withHeader:!1,stringify:!0,escape:!1,quotes:!1},e||{},!0),s=[],l=[],d=[],c=i.config.processData;if(o.processData=a,o.data=void 0!==o.data?i.processData(o):i.getChartData(o),o.withHeader){d=[];for(p in l)isNaN(p)||d.push(r(l[p]));s.push(d)}for(n in o.data)if(d=[],!isNaN(n)){for(p in l)if(!isNaN(p)){var p=l[p],f=o.data[n][p];f=null==f?"":o.stringify?String(f):f,d.push(r(f))}s.push(d)}return i.handleCallback(t,s,o),s},toByteArray:function(e,t){function a(e){var t=e.charCodeAt(0);return t===o?62:t===s?63:t<l?-1:t<l+10?t-l+26+26:t<c+26?t-c:t<d+26?t-d+26:void 0}var r=i.deepMerge({},e||{}),n="undefined"!=typeof Uint8Array?Uint8Array:Array,o="+".charCodeAt(0),s="/".charCodeAt(0),l="0".charCodeAt(0),d="a".charCodeAt(0),c="A".charCodeAt(0),p=function(e){function t(e){d[p++]=e}var i,r,o,s,l,d;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,d=new n(3*e.length/4-l),o=l>0?e.length-4:e.length;var p=0;for(i=0,r=0;i<o;i+=4,r+=3)t((16711680&(s=a(e.charAt(i))<<18|a(e.charAt(i+1))<<12|a(e.charAt(i+2))<<6|a(e.charAt(i+3))))>>16),t((65280&s)>>8),t(255&s);return 2===l?t(255&(s=a(e.charAt(i))<<2|a(e.charAt(i+1))>>4)):1===l&&(t((s=a(e.charAt(i))<<10|a(e.charAt(i+1))<<4|a(e.charAt(i+2))>>2)>>8&255),t(255&s)),d}(r.data);return i.handleCallback(t,p,r),p},removeFunctionsFromObject:function(e){for(var t in e)"function"==typeof e[t]&&delete e[t];return e},handleCallback:function(e){var t,a=Array();if(e&&e instanceof Function){for(t=0;t<arguments.length;t++)t>0&&a.push(arguments[t]);return e.apply(i,a)}},handleLog:function(e){!0===i.config.debug&&console.log(e)},handleNamespace:function(e,t){function a(){var l=Number(new Date);o=!!(e in n),"pdfMake"==e&&o&&(o=n.pdfMake.vfs),o?(clearTimeout(r),t.cb.apply(t.scope,t.args),i.handleLog(['AmCharts [export]: Namespace "',e,'" showed up in: ',String(n)].join(""))):l-s<i.libs.loadTimeout?r=setTimeout(a,250):i.handleLog(['AmCharts [export]: Gave up waiting for "',e,'" in: ',String(n)].join(""))}var r,n=i.config.scope||window,o=!1,s=Number(new Date);return(o=!!(e in n))||(i.handleLog(['AmCharts [export]: Could not find "',e,'" in: ',String(n)].join("")),a()),o},handleBorder:function(e){if(i.config.border instanceof Object){var t=i.deepMerge(i.defaults.fabric.border,e.border||{},!0),a=new fabric.Rect;t.width=i.setup.fabric.width-t.strokeWidth,t.height=i.setup.fabric.height-t.strokeWidth,a.set(t),i.setup.fabric.add(a)}},handleDropbox:function(e){if(i.drawing.enabled)if(e.preventDefault(),e.stopPropagation(),"dragover"==e.type)i.setup.wrapper.setAttribute("class",i.setup.chart.classNamePrefix+"-export-canvas active dropbox");else if(i.setup.wrapper.setAttribute("class",i.setup.chart.classNamePrefix+"-export-canvas active"),"drop"==e.type&&e.dataTransfer.files.length)for(var t=0;t<e.dataTransfer.files.length;t++){var a=new FileReader;a.onloadend=function(t){return function(){i.drawing.handler.add({url:a.result,top:e.layerY-10*t,left:e.layerX-10*t})}}(t),a.readAsDataURL(e.dataTransfer.files[t])}},handleReady:function(e){var t=this,a=Number(new Date);t.handleCallback(e,"data",!1);for(filename in t.libs.namespaces)!function(i){var r=setInterval(function(){var n=Number(new Date);(n-a>t.libs.loadTimeout||i in window)&&(clearTimeout(r),t.handleCallback(e,i,n-a>t.libs.loadTimeout))},AmCharts.updateRate)}(t.libs.namespaces[filename])},getChartData:function(e){function t(e,t,a){function r(e,t){return-1!=s.dataFields.indexOf(e)?r([e,".",t].join("")):e}e&&s.exportTitles&&"gantt"!=i.setup.chart.type&&(g=r(e,a),s.dataFieldsMap[g]=e,s.dataFields.push(g),s.titles[g]=t||g)}var a,r,n,o,s=i.deepMerge({data:[],titles:{},dateFields:[],dataFields:[],dataFieldsMap:{},exportTitles:i.config.exportTitles,exportFields:i.config.exportFields,exportSelection:i.config.exportSelection,columnNames:i.config.columnNames},e||{},!0),l=["valueField","openField","closeField","highField","lowField","xField","yField"];if(0==s.data.length)if("stock"==i.setup.chart.type){for(s.data=i.cloneObject(i.setup.chart.mainDataSet.dataProvider),t(i.setup.chart.mainDataSet.categoryField),s.dateFields.push(i.setup.chart.mainDataSet.categoryField),a=0;a<i.setup.chart.mainDataSet.fieldMappings.length;a++){u=i.setup.chart.mainDataSet.fieldMappings[a];for(r=0;r<i.setup.chart.panels.length;r++){var d=i.setup.chart.panels[r];for(n=0;n<d.stockGraphs.length;n++){v=d.stockGraphs[n];for(i4=0;i4<l.length;i4++)v[l[i4]]==u.toField&&t(u.fromField,v.title,l[i4])}}}if(i.setup.chart.comparedGraphs.length){for(o=[],a=0;a<s.data.length;a++)o.push(s.data[a][i.setup.chart.mainDataSet.categoryField]);for(a=0;a<i.setup.chart.comparedGraphs.length;a++){v=i.setup.chart.comparedGraphs[a];for(r=0;r<v.dataSet.dataProvider.length;r++){var c=v.dataSet.categoryField,p=v.dataSet.dataProvider[r][c],f=o.indexOf(p);if(-1!=f)for(n=0;n<v.dataSet.fieldMappings.length;n++){var u=v.dataSet.fieldMappings[n],g=v.dataSet.id+"_"+u.toField;s.data[f][g]=v.dataSet.dataProvider[r][u.fromField],s.titles[g]||t(g,v.dataSet.title)}}}}}else if("gantt"==i.setup.chart.type){t(i.setup.chart.categoryField);var h=i.setup.chart.segmentsField;for(a=0;a<i.setup.chart.dataProvider.length;a++){var m=i.setup.chart.dataProvider[a];if(m[h])for(r=0;r<m[h].length;r++)m[h][r][i.setup.chart.categoryField]=m[i.setup.chart.categoryField],s.data.push(m[h][r])}for(a=0;a<i.setup.chart.graphs.length;a++){v=i.setup.chart.graphs[a];for(r=0;r<l.length;r++){var b=v[w=l[r]];v.title;t(b,v.title,w)}}}else if(-1!=["pie","funnel"].indexOf(i.setup.chart.type))s.data=i.setup.chart.dataProvider,t(i.setup.chart.titleField),s.dateFields.push(i.setup.chart.titleField),t(i.setup.chart.valueField);else if("map"!=i.setup.chart.type)for(s.data=i.setup.chart.dataProvider,i.setup.chart.categoryAxis&&(t(i.setup.chart.categoryField,i.setup.chart.categoryAxis.title),!1!==i.setup.chart.categoryAxis.parseDates&&s.dateFields.push(i.setup.chart.categoryField)),a=0;a<i.setup.chart.graphs.length;a++){var v=i.setup.chart.graphs[a];for(r=0;r<l.length;r++){var w=l[r];t(b=v[w],v.title,w)}}return i.processData(s)},getAnnotations:function(e,t){var a,r=i.deepMerge({},e||{},!0),n=[];for(a=0;a<i.setup.fabric._objects.length;a++)if(!i.setup.fabric._objects[a].isCoreElement){var o=i.setup.fabric._objects[a].toJSON();i.handleCallback(r.reviver,o,a),n.push(o)}return i.handleCallback(t,n),n},setAnnotations:function(e,t){var a=i.deepMerge({data:[]},e||{},!0);return fabric.util.enlivenObjects(a.data,function(e){e.forEach(function(e,t){i.handleCallback(a.reviver,e,t),i.setup.fabric.add(e)}),i.handleCallback(t,a)}),a.data},processData:function(t){var a,r,n=i.deepMerge({data:[],titles:{},dateFields:[],dataFields:[],dataFieldsMap:{},dataFieldsTitlesMap:{},dataDateFormat:i.setup.chart.dataDateFormat,dateFormat:i.config.dateFormat||i.setup.chart.dataDateFormat||"YYYY-MM-DD",exportTitles:i.config.exportTitles,exportFields:i.config.exportFields,exportSelection:i.config.exportSelection,columnNames:i.config.columnNames,processData:i.config.processData},t||{},!0);if(n.data.length){for(a=0;a<n.data.length;a++)for(r in n.data[a])-1==n.dataFields.indexOf(r)&&(n.dataFields.push(r),n.dataFieldsMap[r]=r);void 0!==n.exportFields&&(n.dataFields=n.exportFields.filter(function(e){return-1!=n.dataFields.indexOf(e)}));var o=[];for(a=0;a<n.data.length;a++){var s={},l=!1;for(r=0;r<n.dataFields.length;r++){var d=n.dataFields[r],c=n.dataFieldsMap[d],p=n.columnNames&&n.columnNames[d]||n.titles[d]||d,f=n.data[a][c];null==f&&(f=void 0),n.exportTitles&&"gantt"!=i.setup.chart.type&&p in s&&(p+=["( ",d," )"].join("")),-1!=n.dateFields.indexOf(c)&&(n.dataDateFormat&&(f instanceof String||"string"==typeof f)?f=AmCharts.stringToDate(f,n.dataDateFormat):n.dateFormat&&(f instanceof Number||"number"==typeof f)&&(f=new Date(f)),n.exportSelection&&(f instanceof Date?(f<e.startDate||f>e.endDate)&&(l=!0):(a<e.startIndex||a>e.endIndex)&&(l=!0)),n.dateFormat&&"dateObject"!=n.dateFormat&&f instanceof Date&&(f=AmCharts.formatDate(f,n.dateFormat))),n.dataFieldsTitlesMap[c]=p,s[p]=f}l||o.push(s)}n.data=o}return void 0!==n.processData&&(n.data=i.handleCallback(n.processData,n.data,n)),n.data},capitalize:function(e){return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()},createMenu:function(t,a){function r(t,a){var o,s,l=document.createElement("ul");for(o=0;o<t.length;o++){var d="string"==typeof t[o]?{format:t[o]}:t[o],c=document.createElement("li"),p=document.createElement("a"),f=document.createElement("img"),u=document.createElement("span"),g=String(d.action?d.action:d.format).toLowerCase();if(d.format=String(d.format).toUpperCase(),c.addEventListener("mouseleave",function(e){this.classList.remove("active")}),p.addEventListener("focus",function(e){if(!i.setup.hasTouch){i.setup.focusedMenuItem=this;var t=this.parentNode;"UL"!=t.tagName&&(t=t.parentNode);var a=t.getElementsByTagName("li");for(o=0;o<a.length;o++)a[o].classList.remove("active");this.parentNode.classList.add("active"),this.parentNode.parentNode.parentNode.classList.add("active")}}),i.config.formats[d.format]?d=i.deepMerge({label:d.icon?"":d.format,format:d.format,mimeType:i.config.formats[d.format].mimeType,extension:i.config.formats[d.format].extension,capture:i.config.formats[d.format].capture,action:i.config.action,fileName:i.config.fileName},d):d.label||(d.label=d.label?d.label:i.i18l("menu.label."+g)),(-1==["CSV","JSON","XLSX"].indexOf(d.format)||-1==["map","gauge"].indexOf(i.setup.chart.type))&&(i.setup.hasBlob||"UNDEFINED"==d.format||!d.mimeType||"image"==d.mimeType.split("/")[0]||"text/plain"==d.mimeType)){if("draw"==d.action)i.config.fabric.drawing.enabled?(d.menu=d.menu?d.menu:i.config.fabric.drawing.menu,d.click=function(e){return function(){this.capture(e,function(){this.createMenu(e.menu)})}}(d)):d.menu=[];else if(!d.populated&&d.action&&-1!=d.action.indexOf("draw.")){var h=d.action.split(".")[1],m=d[h]||i.config.fabric.drawing[h]||[];for(d.menu=[],d.populated=!0,s=0;s<m.length;s++){var b={label:m[s]};if("shapes"==h){var v=-1==m[s].indexOf("//"),w=(v?i.config.path+"shapes/":"")+m[s];b.action="add",b.url=w,b.icon=w,b.ignore=v,b.class="export-drawing-shape"}else"colors"==h?(b.style="background-color: "+m[s],b.action="change",b.color=m[s],b.class="export-drawing-color"):"widths"==h?(b.action="change",b.width=m[s],b.label=document.createElement("span"),b.label.style.width=i.numberToPx(m[s]),b.label.style.height=i.numberToPx(m[s]),b.class="export-drawing-width"):"opacities"==h?(b.style="opacity: "+m[s],b.action="change",b.opacity=m[s],b.label=100*m[s]+"%",b.class="export-drawing-opacity"):"modes"==h&&(b.label=i.i18l("menu.label.draw.modes."+m[s]),b.click=function(e){return function(){i.drawing.mode=e}}(m[s]),b.class="export-drawing-mode");d.menu.push(b)}}else d.click||d.menu||d.items||(i.drawing.handler[g]instanceof Function?(d.action=g,d.click=function(e){return function(){this.drawing.handler[e.action](e),"cancel"!=e.action&&this.createMenu(this.config.fabric.drawing.menu)}}(d)):i.drawing.enabled?d.click=function(e){return function(){this.config.drawing.autoClose&&this.drawing.handler.done(),this["to"+e.format](e,function(t){"download"==e.action&&this.download(t,e.mimeType,[e.fileName,e.extension].join("."))})}}(d):"UNDEFINED"!=d.format&&(d.click=function(e){return function(){if(e.capture||"print"==e.action||"PRINT"==e.format)this.capture(e,function(){this.drawing.handler.done(),this["to"+e.format](e,function(t){"download"==e.action&&(this.download(t,e.mimeType,[e.fileName,e.extension].join(".")),this.createMenu(this.config.menu))})});else{if(!this["to"+e.format])throw new Error("Invalid format. Could not determine output type.");this["to"+e.format](e,function(t){this.download(t,e.mimeType,[e.fileName,e.extension].join(".")),this.createMenu(this.config.menu)})}}}(d)));(void 0===d.menu||d.menu.length)&&(p.setAttribute("href","#"),i.setup.hasTouch&&c.classList?(p.addEventListener("touchend",function(e,t){return function(a){a.preventDefault();var r=[a,t];if(("draw"==t.action||"PRINT"==t.format||"UNDEFINED"!=t.format&&t.capture)&&!i.drawing.enabled&&(!isNaN(t.delay)||!isNaN(i.config.delay)))return t.delay=isNaN(t.delay)?i.config.delay:t.delay,void i.delay(t,e);e.apply(i,r)}}(d.click||function(e){e.preventDefault()},d)),p.addEventListener("touchend",function(e){return function(t){function a(e){return e.classList.contains("export-main")||e.classList.contains("export-drawing")}t.preventDefault();var r=e.elements.li,s=function(e){var t=e.parentNode.parentNode,a=t.classList;return!("LI"!=t.tagName||!a.contains("active"))}(r),l=(function(e){var t=e.parentNode.children;for(o=0;o<t.length;o++){var a=t[o],i=a.classList;if(a!==e&&i.contains("active"))return i.remove("active"),!0}}(r),function(e){return e.getElementsByTagName("ul").length>0}(r));if(!a(r)&&l||i.setup.menu.classList.toggle("active"),!s||!l)for(;n.length;){var d=n.pop(),c=d!==r;a(d)?l||d.classList.remove("active"):c&&d.classList.remove("active")}n.push(r),l&&r.classList.toggle("active")}}(d))):p.addEventListener("click",function(e,t){return function(a){a.preventDefault();var r=[a,t];if(("draw"==t.action||"PRINT"==t.format||"UNDEFINED"!=t.format&&t.capture)&&!i.drawing.enabled&&(!isNaN(t.delay)||!isNaN(i.config.delay)))return t.delay=isNaN(t.delay)?i.config.delay:t.delay,void i.delay(t,e);e.apply(i,r)}}(d.click||function(e){e.preventDefault()},d)),c.appendChild(p),i.isElement(d.label)?u.appendChild(d.label):u.innerHTML=d.label,d.class&&(c.className=d.class),d.style&&c.setAttribute("style",d.style),d.icon&&(f.setAttribute("src",(d.ignore||-1!=d.icon.slice(0,10).indexOf("//")?"":e.pathToImages)+d.icon),p.appendChild(f)),d.label&&p.appendChild(u),d.title&&p.setAttribute("title",d.title),i.config.menuReviver&&(c=i.config.menuReviver.apply(i,[d,c])),d.elements={li:c,a:p,img:f,span:u},(d.menu||d.items)&&"draw"!=d.action?r(d.menu||d.items,c).childNodes.length&&l.appendChild(c):l.appendChild(c))}}return l.childNodes.length&&a.appendChild(l),l}var n=[];return a||("string"==typeof i.config.divId?i.config.divId=a=document.getElementById(i.config.divId):a=i.isElement(i.config.divId)?i.config.divId:i.setup.chart.containerDiv),i.isElement(i.setup.menu)?i.setup.menu.innerHTML="":i.setup.menu=document.createElement("div"),i.setup.menu.setAttribute("class",i.setup.chart.classNamePrefix+"-export-menu "+i.setup.chart.classNamePrefix+"-export-menu-"+i.config.position+" amExportButton"),i.config.menuWalker&&(r=i.config.menuWalker),r.apply(this,[t,i.setup.menu]),i.setup.menu.childNodes.length&&a.appendChild(i.setup.menu),i.setup.menu},delay:function(e,t){var a,r,n=i.deepMerge({delay:3,precision:2},e||{}),o=Number(new Date),s=i.createMenu([{label:i.i18l("capturing.delayed.menu.label").replace("{{duration}}",AmCharts.toFixed(n.delay,n.precision)),title:i.i18l("capturing.delayed.menu.title"),class:"export-delayed-capturing",click:function(){clearTimeout(a),clearTimeout(r),i.createMenu(i.config.menu)}}]).getElementsByTagName("a")[0];a=setInterval(function(){var e=n.delay-(Number(new Date)-o)/1e3;e<=0?(clearTimeout(a),"draw"!=n.action&&i.createMenu(i.config.menu)):s&&(s.innerHTML=i.i18l("capturing.delayed.menu.label").replace("{{duration}}",AmCharts.toFixed(e,2)))},AmCharts.updateRate),r=setTimeout(function(){t.apply(i,arguments)},1e3*n.delay)},migrateSetup:function(e){function t(e){var i;for(i in e){var r=e[i];"export"==i.slice(0,6)&&r?a.menu.push(i.slice(6)):"userCFG"==i?t(r):"menuItems"==i?a.menu=r:"libs"==i?a.libs=r:"string"==typeof i&&(a[i]=r)}}var a={enabled:!0,migrated:!0,libs:{autoLoad:!0},menu:[]};return t(e),a},clear:function(){var e,t;for(void 0!==i.setup.fabric&&i.setup.fabric.removeListeners(),e=0;e<i.listenersToRemove.length;e++)(t=i.listenersToRemove[e]).node.removeEventListener(t.event,t.method);i.isElement(i.setup.wrapper)&&i.isElement(i.setup.wrapper.parentNode)&&i.setup.wrapper.parentNode.removeChild&&i.setup.wrapper.parentNode.removeChild(i.setup.wrapper),i.isElement(i.setup.menu)&&i.isElement(i.setup.wrapper.parentNode)&&i.setup.wrapper.parentNode.removeChild&&i.setup.menu.parentNode.removeChild(i.setup.menu),i.listenersToRemove=[],i.setup.chart.AmExport=void 0,i.setup.chart.export=void 0,i.setup=void 0},loadListeners:function(){function e(e){e&&(e.set({top:e.top+10,left:e.left+10}),i.setup.fabric.add(e))}i.config.keyListener&&"attached"!=i.config.keyListener&&(i.docListener=function(t){function a(e,t){for(i1=0;i1<e.length;i1++){var a=e[i1];a.parentNode.classList.remove("active"),0!=i1||t||a.focus()}}function r(e){i.setup.focusedMenuItem&&i.setup.focusedMenuItem.nextSibling&&(i.setup.focusedMenuItem.parentNode.classList.add("active"),a(i.setup.focusedMenuItem.nextSibling.getElementsByTagName("a"),e))}function n(e){i.setup.focusedMenuItem&&i.setup.focusedMenuItem.parentNode.parentNode.parentNode&&(i.setup.focusedMenuItem.parentNode.classList.add("active"),a(i.setup.focusedMenuItem.parentNode.parentNode.parentNode.getElementsByTagName("a"),e))}var o=i.drawing.buffer.target,s=[37,38,39,40,13,9,27],l=(["top-left","bottom-left"].indexOf(i.config.position),-1!=["top-right","bottom-right"].indexOf(i.config.position));if(i.setup.focusedMenuItem&&-1!=s.indexOf(t.keyCode)){if(9==t.keyCode)return void(i.setup.focusedMenuItem.nextSibling?t.shiftKey&&i.setup.focusedMenuItem.parentNode.classList.remove("active"):(i.setup.focusedMenuItem.parentNode.classList.remove("active"),i.setup.focusedMenuItem.parentNode.nextSibling||(i.setup.focusedMenuItem.parentNode.classList.remove("active"),i.setup.focusedMenuItem.parentNode.parentNode.parentNode.classList.remove("active"))));13==t.keyCode&&i.setup.focusedMenuItem.nextSibling&&r(),37==t.keyCode&&(l?r():n()),39==t.keyCode&&(l?n():r()),40==t.keyCode&&function(e){i.setup.focusedMenuItem&&i.setup.focusedMenuItem.parentNode.nextSibling&&(i.setup.focusedMenuItem.parentNode.classList.remove("active"),a(i.setup.focusedMenuItem.parentNode.nextSibling.getElementsByTagName("a"),e))}(),38==t.keyCode&&function(e){i.setup.focusedMenuItem&&i.setup.focusedMenuItem.parentNode.previousSibling&&(i.setup.focusedMenuItem.parentNode.classList.remove("active"),a(i.setup.focusedMenuItem.parentNode.previousSibling.getElementsByTagName("a"),e))}(),27==t.keyCode&&function(){function e(t){i.isElement(t)&&(t.blur(),t.parentNode&&t.parentNode.classList.remove("active"),t.classList.contains("amExportButton")||e(t.parentNode))}i.setup.focusedMenuItem&&(e(i.setup.focusedMenuItem),i.setup.focusedMenuItem=void 0)}()}8!=t.keyCode&&46!=t.keyCode||!o?27==t.keyCode&&i.drawing.enabled?(t.preventDefault(),i.drawing.buffer.isSelected?i.setup.fabric.discardActiveObject():i.drawing.handler.done()):67==t.keyCode&&(t.metaKey||t.ctrlKey)&&o?i.drawing.buffer.copy=o:88==t.keyCode&&(t.metaKey||t.ctrlKey)&&o?(i.drawing.buffer.copy=o,i.setup.fabric.remove(o)):86==t.keyCode&&(t.metaKey||t.ctrlKey)?i.drawing.buffer.copy&&e(i.drawing.buffer.copy.clone(e)):90==t.keyCode&&(t.metaKey||t.ctrlKey)&&(t.preventDefault(),t.shiftKey?i.drawing.handler.redo():i.drawing.handler.undo()):(t.preventDefault(),i.setup.fabric.remove(o))},i.config.keyListener="attached",document.addEventListener("keydown",i.docListener),i.addListenerToRemove("keydown",document,i.docListener)),i.config.fileListener&&(i.setup.chart.containerDiv.addEventListener("dragover",i.handleDropbox),i.addListenerToRemove("dragover",i.setup.chart.containerDiv,i.handleDropbox),i.setup.chart.containerDiv.addEventListener("dragleave",i.handleDropbox),i.addListenerToRemove("dragleave",i.setup.chart.containerDiv,i.handleDropbox),i.setup.chart.containerDiv.addEventListener("drop",i.handleDropbox),i.addListenerToRemove("drop",i.setup.chart.containerDiv,i.handleDropbox))},init:function(){clearTimeout(a),a=setInterval(function(){i.setup&&i.setup.chart.containerDiv&&(clearTimeout(a),i.config.enabled&&(i.setup.chart.AmExport=i,i.config.overflow&&(i.setup.chart.div.style.overflow="visible"),i.loadListeners(),i.createMenu(i.config.menu),i.handleReady(i.config.onReady)))},AmCharts.updateRate)},construct:function(){i.drawing.handler.cancel=i.drawing.handler.done;try{i.setup.hasBlob=!!new Blob}catch(e){}window.safari=window.safari?window.safari:{},i.defaults.fabric.drawing.fontSize=i.setup.chart.fontSize||11,i.config.drawing=i.deepMerge(i.defaults.fabric.drawing,i.config.drawing||{},!0),i.config.border&&(i.config.border=i.deepMerge(i.defaults.fabric.border,i.config.border||{},!0)),i.deepMerge(i.defaults.fabric,i.config,!0),i.deepMerge(i.defaults.fabric,i.config.fabric||{},!0),i.deepMerge(i.defaults.pdfMake,i.config,!0),i.deepMerge(i.defaults.pdfMake,i.config.pdfMake||{},!0),i.deepMerge(i.libs,i.config.libs||{},!0),i.config.drawing=i.defaults.fabric.drawing,i.config.fabric=i.defaults.fabric,i.config.pdfMake=i.defaults.pdfMake,i.config=i.deepMerge(i.defaults,i.config,!0),i.config.fabric.drawing.enabled&&void 0===i.config.fabric.drawing.menu&&(i.config.fabric.drawing.menu=[],i.deepMerge(i.config.fabric.drawing.menu,[{class:"export-drawing",menu:[{label:i.i18l("menu.label.draw.add"),menu:[{label:i.i18l("menu.label.draw.shapes"),action:"draw.shapes"},{label:i.i18l("menu.label.draw.text"),action:"text"}]},{label:i.i18l("menu.label.draw.change"),menu:[{label:i.i18l("menu.label.draw.modes"),action:"draw.modes"},{label:i.i18l("menu.label.draw.colors"),action:"draw.colors"},{label:i.i18l("menu.label.draw.widths"),action:"draw.widths"},{label:i.i18l("menu.label.draw.opacities"),action:"draw.opacities"},"UNDO","REDO"]},{label:i.i18l("menu.label.save.image"),menu:["PNG","JPG","SVG","PDF"]},"PRINT","CANCEL"]}])),void 0===i.config.menu&&(i.config.menu=[],i.deepMerge(i.config,{menu:[{class:"export-main",menu:[{label:i.i18l("menu.label.save.image"),menu:["PNG","JPG","SVG","PDF"]},{label:i.i18l("menu.label.save.data"),menu:["CSV","XLSX","JSON"]},{label:i.i18l("menu.label.draw"),action:"draw",menu:i.config.fabric.drawing.menu},{format:"PRINT",label:i.i18l("menu.label.print")}]}]})),i.libs.path||(i.libs.path=i.config.path+"libs/"),i.isSupported()&&(i.loadDependencies(i.libs.resources,i.libs.reload),i.setup.chart.addClassNames=!0,i.setup.chart[i.name]=i,i.init())}};if(t)i.config=t;else if(i.setup.chart[i.name])i.config=i.setup.chart[i.name];else{if(!i.setup.chart.amExport&&!i.setup.chart.exportConfig)return;i.config=i.migrateSetup(i.setup.chart.amExport||i.setup.chart.exportConfig)}return i.construct(),i.deepMerge(this,i)}}(),AmCharts.addInitHandler(function(e){new AmCharts.export(e)},["pie","serial","xy","funnel","radar","gauge","stock","map","gantt"]); diff --git a/admin/src/main/resources/static/js/plugins/chart/light.js b/admin/src/main/resources/static/js/plugins/chart/light.js deleted file mode 100755 index 5ef906abc075106fba39b01b1e65252f70784d3e..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/light.js +++ /dev/null @@ -1 +0,0 @@ -AmCharts.themes.light={themeName:"light",AmChart:{color:"#000000",backgroundColor:"#FFFFFF"},AmCoordinateChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"]},AmStockChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"]},AmSlicedChart:{colors:["#67b7dc","#fdd400","#84b761","#cc4748","#cd82ad","#2f4074","#448e4d","#b7b83f","#b9783f","#b93e3d","#913167"],outlineAlpha:1,outlineThickness:2,labelTickColor:"#000000",labelTickAlpha:0.3},AmRectangularChart:{zoomOutButtonColor:'#000000',zoomOutButtonRollOverAlpha:0.15,zoomOutButtonImage:"lens"},AxisBase:{axisColor:"#000000",axisAlpha:0.3,gridAlpha:0.1,gridColor:"#000000"},ChartScrollbar:{backgroundColor:"#000000",backgroundAlpha:0.12,graphFillAlpha:0.5,graphLineAlpha:0,selectedBackgroundColor:"#FFFFFF",selectedBackgroundAlpha:0.4,gridAlpha:0.15},ChartCursor:{cursorColor:"#000000",color:"#FFFFFF",cursorAlpha:0.5},AmLegend:{color:"#000000"},AmGraph:{lineAlpha:0.9},GaugeArrow:{color:"#000000",alpha:0.8,nailAlpha:0,innerRadius:"40%",nailRadius:15,startWidth:15,borderAlpha:0.8,nailBorderAlpha:0},GaugeAxis:{tickColor:"#000000",tickAlpha:1,tickLength:15,minorTickLength:8,axisThickness:3,axisColor:'#000000',axisAlpha:1,bandAlpha:0.8},TrendLine:{lineColor:"#c03246",lineAlpha:0.8},AreasSettings:{alpha:0.8,color:"#67b7dc",colorSolid:"#003767",unlistedAreasAlpha:0.4,unlistedAreasColor:"#000000",outlineColor:"#FFFFFF",outlineAlpha:0.5,outlineThickness:0.5,rollOverColor:"#3c5bdc",rollOverOutlineColor:"#FFFFFF",selectedOutlineColor:"#FFFFFF",selectedColor:"#f15135",unlistedAreasOutlineColor:"#FFFFFF",unlistedAreasOutlineAlpha:0.5},LinesSettings:{color:"#000000",alpha:0.8},ImagesSettings:{alpha:0.8,labelColor:"#000000",color:"#000000",labelRollOverColor:"#3c5bdc"},ZoomControl:{buttonFillAlpha:0.7,buttonIconColor:"#a7a7a7"},SmallMap:{mapColor:"#000000",rectangleColor:"#f15135",backgroundColor:"#FFFFFF",backgroundAlpha:0.7,borderThickness:1,borderAlpha:0.8},PeriodSelector:{color:"#000000"},PeriodButton:{color:"#000000",background:"transparent",opacity:0.7,border:"1px solid rgba(0, 0, 0, .3)",MozBorderRadius:"5px",borderRadius:"5px",margin:"1px",outline:"none",boxSizing:"border-box"},PeriodButtonSelected:{color:"#000000",backgroundColor:"#b9cdf5",border:"1px solid rgba(0, 0, 0, .3)",MozBorderRadius:"5px",borderRadius:"5px",margin:"1px",outline:"none",opacity:1,boxSizing:"border-box"},PeriodInputField:{color:"#000000",background:"transparent",border:"1px solid rgba(0, 0, 0, .3)",outline:"none"},DataSetSelector:{color:"#000000",selectedBackgroundColor:"#b9cdf5",rollOverBackgroundColor:"#a8b0e4"},DataSetCompareList:{color:"#000000",lineHeight:"100%",boxSizing:"initial",webkitBoxSizing:"initial",border:"1px solid rgba(0, 0, 0, .3)"},DataSetSelect:{border:"1px solid rgba(0, 0, 0, .3)",outline:"none"}}; diff --git a/admin/src/main/resources/static/js/plugins/chart/serial.js b/admin/src/main/resources/static/js/plugins/chart/serial.js deleted file mode 100755 index 56d7a841b9f6cb5da36a8eb0dbfeee9911c562db..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/chart/serial.js +++ /dev/null @@ -1,15 +0,0 @@ -(function(){var f=window.AmCharts;f.AmRectangularChart=f.Class({inherits:f.AmCoordinateChart,construct:function(a){f.AmRectangularChart.base.construct.call(this,a);this.theme=a;this.createEvents("zoomed","changed");this.marginRight=this.marginBottom=this.marginTop=this.marginLeft=20;this.depth3D=this.angle=0;this.plotAreaFillColors="#FFFFFF";this.plotAreaFillAlphas=0;this.plotAreaBorderColor="#000000";this.plotAreaBorderAlpha=0;this.maxZoomFactor=20;this.zoomOutButtonImageSize=19;this.zoomOutButtonImage="lens";this.zoomOutText="Show all";this.zoomOutButtonColor="#e5e5e5";this.zoomOutButtonAlpha=0;this.zoomOutButtonRollOverAlpha=1;this.zoomOutButtonPadding=8;this.trendLines=[];this.autoMargins=!0;this.marginsUpdated=!1;this.autoMarginOffset=10;f.applyTheme(this,a,"AmRectangularChart")},initChart:function(){f.AmRectangularChart.base.initChart.call(this);this.updateDxy();!this.marginsUpdated&&this.autoMargins&&(this.resetMargins(),this.drawGraphs=!1);this.processScrollbars();this.updateMargins();this.updatePlotArea();this.updateScrollbars();this.updateTrendLines();this.updateChartCursor();this.updateValueAxes();this.scrollbarOnly||this.updateGraphs()},drawChart:function(){f.AmRectangularChart.base.drawChart.call(this);this.drawPlotArea();if(f.ifArray(this.chartData)){var a=this.chartCursor;a&&a.draw()}},resetMargins:function(){var a={},b;if("xy"==this.type){var c=this.xAxes,d=this.yAxes;for(b=0;b<c.length;b++){var g=c[b];g.ignoreAxisWidth||(g.setOrientation(!0),g.fixAxisPosition(),a[g.position]=!0)}for(b=0;b<d.length;b++)c=d[b],c.ignoreAxisWidth||(c.setOrientation(!1),c.fixAxisPosition(),a[c.position]=!0)}else{d=this.valueAxes;for(b=0;b<d.length;b++)c=d[b],c.ignoreAxisWidth||(c.setOrientation(this.rotate),c.fixAxisPosition(),a[c.position]=!0);(b=this.categoryAxis)&&!b.ignoreAxisWidth&&(b.setOrientation(!this.rotate),b.fixAxisPosition(),b.fixAxisPosition(),a[b.position]=!0)}a.left&&(this.marginLeft=0);a.right&&(this.marginRight=0);a.top&&(this.marginTop=0);a.bottom&&(this.marginBottom=0);this.fixMargins=a},measureMargins:function(){var a=this.valueAxes,b,c=this.autoMarginOffset,d=this.fixMargins,g=this.realWidth,h=this.realHeight,e=c,f=c,k=g;b=h;var m;for(m=0;m<a.length;m++)a[m].handleSynchronization(),b=this.getAxisBounds(a[m],e,k,f,b),e=Math.round(b.l),k=Math.round(b.r),f=Math.round(b.t),b=Math.round(b.b);if(a=this.categoryAxis)b=this.getAxisBounds(a,e,k,f,b),e=Math.round(b.l),k=Math.round(b.r),f=Math.round(b.t),b=Math.round(b.b);d.left&&e<c&&(this.marginLeft=Math.round(-e+c),!isNaN(this.minMarginLeft)&&this.marginLeft<this.minMarginLeft&&(this.marginLeft=this.minMarginLeft));d.right&&k>=g-c&&(this.marginRight=Math.round(k-g+c),!isNaN(this.minMarginRight)&&this.marginRight<this.minMarginRight&&(this.marginRight=this.minMarginRight));d.top&&f<c+this.titleHeight&&(this.marginTop=Math.round(this.marginTop-f+c+this.titleHeight),!isNaN(this.minMarginTop)&&this.marginTop<this.minMarginTop&&(this.marginTop=this.minMarginTop));d.bottom&&b>h-c&&(this.marginBottom=Math.round(this.marginBottom+b-h+c),!isNaN(this.minMarginBottom)&&this.marginBottom<this.minMarginBottom&&(this.marginBottom=this.minMarginBottom));this.initChart()},getAxisBounds:function(a,b,c,d,g){if(!a.ignoreAxisWidth){var h=a.labelsSet,e=a.tickLength;a.inside&&(e=0);if(h)switch(h=a.getBBox(),a.position){case"top":a=h.y;d>a&&(d=a);break;case"bottom":a=h.y+h.height;g<a&&(g=a);break;case"right":a=h.x+h.width+e+3;c<a&&(c=a);break;case"left":a=h.x-e,b>a&&(b=a)}}return{l:b,t:d,r:c,b:g}},drawZoomOutButton:function(){var a=this;if(!a.zbSet){var b=a.container.set();a.zoomButtonSet.push(b);var c=a.color,d=a.fontSize,g=a.zoomOutButtonImageSize,h=a.zoomOutButtonImage.replace(/\.[a-z]*$/i,""),e=a.langObj.zoomOutText||a.zoomOutText,l=a.zoomOutButtonColor,k=a.zoomOutButtonAlpha,m=a.zoomOutButtonFontSize,p=a.zoomOutButtonPadding;isNaN(m)||(d=m);(m=a.zoomOutButtonFontColor)&&(c=m);var m=a.zoomOutButton,n;m&&(m.fontSize&&(d=m.fontSize),m.color&&(c=m.color),m.backgroundColor&&(l=m.backgroundColor),isNaN(m.backgroundAlpha)||(a.zoomOutButtonRollOverAlpha=m.backgroundAlpha));var u=m=0,u=a.pathToImages;if(h){if(f.isAbsolute(h)||void 0===u)u="";n=a.container.image(u+h+a.extension,0,0,g,g);f.setCN(a,n,"zoom-out-image");b.push(n);n=n.getBBox();m=n.width+5}void 0!==e&&(c=f.text(a.container,e,c,a.fontFamily,d,"start"),f.setCN(a,c,"zoom-out-label"),d=c.getBBox(),u=n?n.height/2-3:d.height/2,c.translate(m,u),b.push(c));n=b.getBBox();c=1;f.isModern||(c=0);l=f.rect(a.container,n.width+2*p+5,n.height+2*p-2,l,1,1,l,c);l.setAttr("opacity",k);l.translate(-p,-p);f.setCN(a,l,"zoom-out-bg");b.push(l);l.toBack();a.zbBG=l;n=l.getBBox();b.translate(a.marginLeftReal+a.plotAreaWidth-n.width+p,a.marginTopReal+p);b.hide();b.mouseover(function(){a.rollOverZB()}).mouseout(function(){a.rollOutZB()}).click(function(){a.clickZB()}).touchstart(function(){a.rollOverZB()}).touchend(function(){a.rollOutZB();a.clickZB()});for(k=0;k<b.length;k++)b[k].attr({cursor:"pointer"});void 0!==a.zoomOutButtonTabIndex&&(b.setAttr("tabindex",a.zoomOutButtonTabIndex),b.setAttr("role","menuitem"),b.keyup(function(b){13==b.keyCode&&a.clickZB()}));a.zbSet=b}},rollOverZB:function(){this.rolledOverZB=!0;this.zbBG.setAttr("opacity",this.zoomOutButtonRollOverAlpha)},rollOutZB:function(){this.rolledOverZB=!1;this.zbBG.setAttr("opacity",this.zoomOutButtonAlpha)},clickZB:function(){this.rolledOverZB=!1;this.zoomOut()},zoomOut:function(){this.zoomOutValueAxes()},drawPlotArea:function(){var a=this.dx,b=this.dy,c=this.marginLeftReal,d=this.marginTopReal,g=this.plotAreaWidth-1,h=this.plotAreaHeight-1,e=this.plotAreaFillColors,l=this.plotAreaFillAlphas,k=this.plotAreaBorderColor,m=this.plotAreaBorderAlpha;"object"==typeof l&&(l=l[0]);e=f.polygon(this.container,[0,g,g,0,0],[0,0,h,h,0],e,l,1,k,m,this.plotAreaGradientAngle);f.setCN(this,e,"plot-area");e.translate(c+a,d+b);this.set.push(e);0!==a&&0!==b&&(e=this.plotAreaFillColors,"object"==typeof e&&(e=e[0]),e=f.adjustLuminosity(e,-.15),g=f.polygon(this.container,[0,a,g+a,g,0],[0,b,b,0,0],e,l,1,k,m),f.setCN(this,g,"plot-area-bottom"),g.translate(c,d+h),this.set.push(g),a=f.polygon(this.container,[0,0,a,a,0],[0,h,h+b,b,0],e,l,1,k,m),f.setCN(this,a,"plot-area-left"),a.translate(c,d),this.set.push(a));(c=this.bbset)&&this.scrollbarOnly&&c.remove()},updatePlotArea:function(){var a=this.updateWidth(),b=this.updateHeight(),c=this.container;this.realWidth=a;this.realWidth=b;c&&this.container.setSize(a,b);var c=this.marginLeftReal,d=this.marginTopReal,a=a-c-this.marginRightReal-this.dx,b=b-d-this.marginBottomReal;1>a&&(a=1);1>b&&(b=1);this.plotAreaWidth=Math.round(a);this.plotAreaHeight=Math.round(b);this.plotBalloonsSet.translate(c,d)},updateDxy:function(){this.dx=Math.round(this.depth3D*Math.cos(this.angle*Math.PI/180));this.dy=Math.round(-this.depth3D*Math.sin(this.angle*Math.PI/180));this.d3x=Math.round(this.columnSpacing3D*Math.cos(this.angle*Math.PI/180));this.d3y=Math.round(-this.columnSpacing3D*Math.sin(this.angle*Math.PI/180))},updateMargins:function(){var a=this.getTitleHeight();this.titleHeight=a;this.marginTopReal=this.marginTop-this.dy;this.fixMargins&&!this.fixMargins.top&&(this.marginTopReal+=a);this.marginBottomReal=this.marginBottom;this.marginLeftReal=this.marginLeft;this.marginRightReal=this.marginRight},updateValueAxes:function(){var a=this.valueAxes,b;for(b=0;b<a.length;b++){var c=a[b];this.setAxisRenderers(c);this.updateObjectSize(c)}},setAxisRenderers:function(a){a.axisRenderer=f.RecAxis;a.guideFillRenderer=f.RecFill;a.axisItemRenderer=f.RecItem;a.marginsChanged=!0},updateGraphs:function(){var a=this.graphs,b;for(b=0;b<a.length;b++){var c=a[b];c.index=b;c.rotate=this.rotate;this.updateObjectSize(c)}},updateObjectSize:function(a){a.width=this.plotAreaWidth-1;a.height=this.plotAreaHeight-1;a.x=this.marginLeftReal;a.y=this.marginTopReal;a.dx=this.dx;a.dy=this.dy},updateChartCursor:function(){var a=this.chartCursor;a&&(a=f.processObject(a,f.ChartCursor,this.theme),this.updateObjectSize(a),this.addChartCursor(a),a.chart=this)},processScrollbars:function(){var a=this.chartScrollbar;a&&(a=f.processObject(a,f.ChartScrollbar,this.theme),this.addChartScrollbar(a))},updateScrollbars:function(){},removeChartCursor:function(){f.callMethod("destroy",[this.chartCursor]);this.chartCursor=null},zoomTrendLines:function(){var a=this.trendLines,b;for(b=0;b<a.length;b++){var c=a[b];c.valueAxis.recalculateToPercents?c.set&&c.set.hide():(c.x=this.marginLeftReal,c.y=this.marginTopReal,c.draw())}},handleCursorValueZoom:function(){},addTrendLine:function(a){this.trendLines.push(a)},zoomOutValueAxes:function(){for(var a=this.valueAxes,b=0;b<a.length;b++)a[b].zoomOut()},removeTrendLine:function(a){var b=this.trendLines,c;for(c=b.length-1;0<=c;c--)b[c]==a&&b.splice(c,1)},adjustMargins:function(a,b){var c=a.position,d=a.scrollbarHeight+a.offset;a.enabled&&("top"==c?b?this.marginLeftReal+=d:this.marginTopReal+=d:b?this.marginRightReal+=d:this.marginBottomReal+=d)},getScrollbarPosition:function(a,b,c){var d="bottom",g="top";a.oppositeAxis||(g=d,d="top");a.position=b?"bottom"==c||"left"==c?d:g:"top"==c||"right"==c?d:g},updateChartScrollbar:function(a,b){if(a){a.rotate=b;var c=this.marginTopReal,d=this.marginLeftReal,g=a.scrollbarHeight,h=this.dx,e=this.dy,f=a.offset;"top"==a.position?b?(a.y=c,a.x=d-g-f):(a.y=c-g+e-f,a.x=d+h):b?(a.y=c+e,a.x=d+this.plotAreaWidth+h+f):(a.y=c+this.plotAreaHeight+f,a.x=this.marginLeftReal)}},showZB:function(a){var b=this.zbSet;a&&(b=this.zoomOutText,""!==b&&b&&this.drawZoomOutButton());if(b=this.zbSet)this.zoomButtonSet.push(b),a?b.show():b.hide(),this.rollOutZB()},handleReleaseOutside:function(a){f.AmRectangularChart.base.handleReleaseOutside.call(this,a);(a=this.chartCursor)&&a.handleReleaseOutside&&a.handleReleaseOutside()},handleMouseDown:function(a){f.AmRectangularChart.base.handleMouseDown.call(this,a);var b=this.chartCursor;b&&b.handleMouseDown&&!this.rolledOverZB&&b.handleMouseDown(a)},update:function(){f.AmRectangularChart.base.update.call(this);this.chartCursor&&this.chartCursor.update&&this.chartCursor.update()},handleScrollbarValueZoom:function(a){this.relativeZoomValueAxes(a.target.valueAxes,a.relativeStart,a.relativeEnd);this.zoomAxesAndGraphs()},zoomValueScrollbar:function(a){if(a&&a.enabled){var b=a.valueAxes[0],c=b.relativeStart,d=b.relativeEnd;b.reversed&&(d=1-c,c=1-b.relativeEnd);a.percentZoom(c,d)}},zoomAxesAndGraphs:function(){if(!this.scrollbarOnly){var a=this.valueAxes,b;for(b=0;b<a.length;b++)a[b].zoom(this.start,this.end);a=this.graphs;for(b=0;b<a.length;b++)a[b].zoom(this.start,this.end);(b=this.chartCursor)&&b.clearSelection();this.zoomTrendLines()}},handleValueAxisZoomReal:function(a,b){var c=a.relativeStart,d=a.relativeEnd;if(c>d)var g=c,c=d,d=g;this.relativeZoomValueAxes(b,c,d);this.updateAfterValueZoom()},updateAfterValueZoom:function(){this.zoomAxesAndGraphs();this.zoomScrollbar()},relativeZoomValueAxes:function(a,b,c){this.hideBalloonReal();b=f.fitToBounds(b,0,1);c=f.fitToBounds(c,0,1);if(b>c){var d=b;b=c;c=d}var d=1/this.maxZoomFactor,g=f.getDecimals(d)+4;c-b<d&&(c=b+(c-b)/2,b=c-d/2,c+=d/2,1<c&&(b-=c-1,c=1),0>b&&(b=0,c=d));b=f.roundTo(b,g);c=f.roundTo(c,g);d=!1;if(a){for(g=0;g<a.length;g++){var h=a[g].zoomToRelativeValues(b,c,!0);h&&(d=h)}this.showZB()}return d},addChartCursor:function(a){f.callMethod("destroy", -[this.chartCursor]);a&&(this.listenTo(a,"moved",this.handleCursorMove),this.listenTo(a,"zoomed",this.handleCursorZoom),this.listenTo(a,"zoomStarted",this.handleCursorZoomStarted),this.listenTo(a,"panning",this.handleCursorPanning),this.listenTo(a,"onHideCursor",this.handleCursorHide));this.chartCursor=a},handleCursorChange:function(){},handleCursorMove:function(a){var b,c=this.valueAxes;for(b=0;b<c.length;b++)if(!a.panning){var d=c[b];d&&d.showBalloon&&d.showBalloon(a.x,a.y)}},handleCursorZoom:function(a){if(this.skipZoomed)this.skipZoomed=!1;else{var b=this.startX0,c=this.endX0,d=this.endY0,g=this.startY0,h=a.startX,e=a.endX,f=a.startY,k=a.endY;this.startX0=this.endX0=this.startY0=this.endY0=NaN;this.handleCursorZoomReal(b+h*(c-b),b+e*(c-b),g+f*(d-g),g+k*(d-g),a)}},handleCursorHide:function(){var a,b=this.valueAxes;for(a=0;a<b.length;a++)b[a].hideBalloon();b=this.graphs;for(a=0;a<b.length;a++)b[a].hideBalloonReal()}})})();(function(){var f=window.AmCharts;f.AmSerialChart=f.Class({inherits:f.AmRectangularChart,construct:function(a){this.type="serial";f.AmSerialChart.base.construct.call(this,a);this.cname="AmSerialChart";this.theme=a;this.columnSpacing=5;this.columnSpacing3D=0;this.columnWidth=.8;var b=new f.CategoryAxis(a);b.chart=this;this.categoryAxis=b;this.zoomOutOnDataUpdate=!0;this.mouseWheelZoomEnabled=this.mouseWheelScrollEnabled=this.rotate=this.skipZoom=!1;this.minSelectedTime=0;f.applyTheme(this,a,this.cname)},initChart:function(){f.AmSerialChart.base.initChart.call(this);this.updateCategoryAxis(this.categoryAxis,this.rotate,"categoryAxis");if(this.dataChanged)this.parseData();else this.onDataUpdated();this.drawGraphs=!0},onDataUpdated:function(){var a=this.countColumns(),b=this.chartData,c=this.graphs,d;for(d=0;d<c.length;d++){var g=c[d];g.data=b;g.columnCount=a}0<b.length&&(this.firstTime=this.getStartTime(b[0].time),this.lastTime=this.getEndTime(b[b.length-1].time));this.drawChart();this.autoMargins&&!this.marginsUpdated?(this.marginsUpdated=!0,this.measureMargins()):this.dispDUpd()},syncGrid:function(){if(this.synchronizeGrid){var a=this.valueAxes,b,c;if(0<a.length){var d=0;for(c=0;c<a.length;c++)b=a[c],d<b.gridCountReal&&(d=b.gridCountReal);var g=!1;for(c=0;c<a.length;c++)if(b=a[c],b.gridCountReal<d){var h=(d-b.gridCountReal)/2,e=g=h;0!==h-Math.round(h)&&(g-=.5,e+=.5);0<=b.min&&0>b.min-g*b.step&&(e+=g,g=0);0>=b.max&&0<b.max+e*b.step&&(g+=e,e=0);h=f.getDecimals(b.step);b.minimum=f.roundTo(b.min- -g*b.step,h);b.maximum=f.roundTo(b.max+e*b.step,h);b.setStep=b.step;g=b.strictMinMax=!0}g&&this.updateAfterValueZoom();for(c=0;c<a.length;c++)b=a[c],b.minimum=NaN,b.maximum=NaN,b.setStep=NaN,b.strictMinMax=!1}}},handleWheelReal:function(a,b){if(!this.wheelBusy){var c=this.categoryAxis,d=c.parseDates,g=c.minDuration(),h=1,e=1;this.mouseWheelZoomEnabled?b||(h=-1):b&&(h=-1);var f=this.chartCursor;if(f){var k=f.mouseX,f=f.mouseY;h!=e&&(k=this.rotate?f/this.plotAreaHeight:k/this.plotAreaWidth,h*=k,e*=1- -k);k=.05*(this.end-this.start);d&&(k=.05*(this.endTime-this.startTime)/g);1>k&&(k=1);h*=k;e*=k;if(!d||c.equalSpacing)h=Math.round(h),e=Math.round(e)}f=this.chartData.length;c=this.lastTime;k=this.firstTime;0>a?d?(f=this.endTime-this.startTime,d=this.startTime+h*g,g=this.endTime+e*g,0<e&&0<h&&g>=c&&(g=c,d=c-f),this.zoomToDates(new Date(d),new Date(g))):(0<e&&0<h&&this.end>=f-1&&(h=e=0),d=this.start+h,g=this.end+e,this.zoomToIndexes(d,g)):d?(f=this.endTime-this.startTime,d=this.startTime-h*g,g=this.endTime- -e*g,0<e&&0<h&&d<=k&&(d=k,g=k+f),this.zoomToDates(new Date(d),new Date(g))):(0<e&&0<h&&1>this.start&&(h=e=0),d=this.start-h,g=this.end-e,this.zoomToIndexes(d,g))}},validateData:function(a){this.marginsUpdated=!1;this.zoomOutOnDataUpdate&&!a&&(this.endTime=this.end=this.startTime=this.start=NaN);var b=a=!1,c=!1,d=this.chartScrollbar;d&&(d.dragging&&(a=!0,d.handleDragStop()),d.resizingRight&&(c=!0,d.rightDragStop()),d.resizingLeft&&(b=!0,d.leftDragStop()));f.AmSerialChart.base.validateData.call(this);a&&d.handleDragStart();c&&d.rightDragStart();b&&d.leftDragStart()},drawChart:function(){if(0<this.realWidth&&0<this.realHeight){f.AmSerialChart.base.drawChart.call(this);var a=this.chartData;if(f.ifArray(a)){var b=this.chartScrollbar;!b||!this.marginsUpdated&&this.autoMargins||b.draw();(b=this.valueScrollbar)&&b.draw();var b=a.length-1,c,d;c=this.categoryAxis;if(c.parseDates&&!c.equalSpacing){if(c=this.startTime,d=this.endTime,isNaN(c)||isNaN(d))c=this.firstTime,d=this.lastTime}else{c=this.start;d=this.end;if(isNaN(c)||isNaN(d))d=c=NaN;isNaN(c)&&(isNaN(this.startTime)||(c=this.getClosestIndex(a,"time",this.startTime,!0,0,a.length)));isNaN(d)&&(isNaN(this.endTime)||(d=this.getClosestIndex(a,"time",this.endTime,!1,0,a.length)));if(isNaN(c)||isNaN(d))c=0,d=b}this.endTime=this.startTime=this.end=this.start=void 0;this.zoom(c,d)}}else this.cleanChart()},cleanChart:function(){f.callMethod("destroy",[this.valueAxes,this.graphs,this.categoryAxis,this.chartScrollbar,this.chartCursor,this.valueScrollbar])},updateCategoryAxis:function(a,b,c){a.chart=this;a.id=c;a.rotate=b;a.setOrientation(!this.rotate);a.init();this.setAxisRenderers(a);this.updateObjectSize(a)},updateValueAxes:function(){f.AmSerialChart.base.updateValueAxes.call(this);var a=this.valueAxes,b;for(b=0;b<a.length;b++){var c=a[b],d=this.rotate;c.rotate=d;c.setOrientation(d);d=this.categoryAxis;if(!d.startOnAxis||d.parseDates)c.expandMinMax=!0}},getStartTime:function(a){var b=this.categoryAxis;return f.resetDateToMin(new Date(a),b.minPeriod,1,b.firstDayOfWeek).getTime()},getEndTime:function(a){var b=f.extractPeriod(this.categoryAxis.minPeriod);return f.changeDate(new Date(a),b.period,b.count,!0).getTime()-1},updateMargins:function(){f.AmSerialChart.base.updateMargins.call(this);var a=this.chartScrollbar;a&&(this.getScrollbarPosition(a,this.rotate,this.categoryAxis.position),this.adjustMargins(a,this.rotate));if(a=this.valueScrollbar)this.getScrollbarPosition(a,!this.rotate,this.valueAxes[0].position),this.adjustMargins(a,!this.rotate)},updateScrollbars:function(){f.AmSerialChart.base.updateScrollbars.call(this);this.updateChartScrollbar(this.chartScrollbar,this.rotate);this.updateChartScrollbar(this.valueScrollbar,!this.rotate)},zoom:function(a,b){var c=this.categoryAxis;c.parseDates&&!c.equalSpacing?(this.timeZoom(a,b),isNaN(a)&&this.zoomOutValueAxes()):this.indexZoom(a,b);(c=this.chartCursor)&&(c.pan||c.hideCursorReal());this.updateLegendValues()},timeZoom:function(a,b){var c=this.maxSelectedTime;isNaN(c)||(b!=this.endTime&&b- -a>c&&(a=b-c),a!=this.startTime&&b-a>c&&(b=a+c));var d=this.minSelectedTime;if(0<d&&b-a<d){var g=Math.round(a+(b-a)/2),d=Math.round(d/2);a=g-d;b=g+d}d=this.chartData;g=this.categoryAxis;if(f.ifArray(d)&&(a!=this.startTime||b!=this.endTime)){var h=g.minDuration(),e=this.firstTime,l=this.lastTime;a||(a=e,isNaN(c)||(a=l-c));b||(b=l);a>l&&(a=l);b<e&&(b=e);a<e&&(a=e);b>l&&(b=l);b<a&&(b=a+h);b-a<h/5&&(b<l?b=a+h/5:a=b-h/5);this.startTime=a;this.endTime=b;c=d.length-1;h=this.getClosestIndex(d,"time",a,!0, -0,c);d=this.getClosestIndex(d,"time",b,!1,h,c);g.timeZoom(a,b);g.zoom(h,d);this.start=f.fitToBounds(h,0,c);this.end=f.fitToBounds(d,0,c);this.zoomAxesAndGraphs();this.zoomScrollbar();this.fixCursor();this.showZB();this.syncGrid();this.updateColumnsDepth();this.dispatchTimeZoomEvent()}},showZB:function(){var a,b=this.categoryAxis;b&&b.parseDates&&!b.equalSpacing&&(this.startTime>this.firstTime&&(a=!0),this.endTime<this.lastTime&&(a=!0));0<this.start&&(a=!0);this.end<this.chartData.length-1&&(a=!0);if(b=this.valueAxes)b=b[0],isNaN(b.relativeStart)||(0!==f.roundTo(b.relativeStart,3)&&(a=!0),1!=f.roundTo(b.relativeEnd,3)&&(a=!0));f.AmSerialChart.base.showZB.call(this,a)},updateAfterValueZoom:function(){f.AmSerialChart.base.updateAfterValueZoom.call(this);this.updateColumnsDepth()},indexZoom:function(a,b){var c=this.maxSelectedSeries,d=!1;isNaN(c)||(b!=this.end&&b-a>c&&(a=b-c,d=!0),a!=this.start&&b-a>c&&(b=a+c,d=!0));if(d&&(d=this.chartScrollbar)&&d.dragger){var g=d.dragger.getBBox();d.maxWidth=g.width;d.maxHeight=g.height}if(a!=this.start||b!=this.end)d=this.chartData.length-1,isNaN(a)&&(a=0,isNaN(c)||(a=d-c)),isNaN(b)&&(b=d),b<a&&(b=a),b>d&&(b=d),a>d&&(a=d-1),0>a&&(a=0),this.start=a,this.end=b,this.categoryAxis.zoom(a,b),this.zoomAxesAndGraphs(),this.zoomScrollbar(),this.fixCursor(),0!==a||b!=this.chartData.length-1?this.showZB(!0):this.showZB(!1),this.syncGrid(),this.updateColumnsDepth(),this.dispatchIndexZoomEvent()},updateGraphs:function(){f.AmSerialChart.base.updateGraphs.call(this);var a=this.graphs,b;for(b=0;b<a.length;b++){var c=a[b];c.columnWidthReal=this.columnWidth;c.categoryAxis=this.categoryAxis;f.isString(c.fillToGraph)&&(c.fillToGraph=this.graphsById[c.fillToGraph])}},zoomAxesAndGraphs:function(){f.AmSerialChart.base.zoomAxesAndGraphs.call(this);this.updateColumnsDepth()},updateColumnsDepth:function(){if(0!==this.depth3D||0!==this.angle){var a,b=this.graphs,c;this.columnsArray=[];for(a=0;a<b.length;a++){c=b[a];var d=c.columnsArray;if(d){var g;for(g=0;g<d.length;g++)this.columnsArray.push(d[g])}}this.columnsArray.sort(this.compareDepth);b=this.columnsSet;if(0<this.columnsArray.length){d=this.container.set();this.columnSet.push(d);for(a=0;a<this.columnsArray.length;a++)d.push(this.columnsArray[a].column.set);c&&d.translate(c.x,c.y);this.columnsSet=d}f.remove(b)}},compareDepth:function(a,b){return a.depth>b.depth?1:-1},zoomScrollbar:function(){var a=this.chartScrollbar,b=this.categoryAxis;if(a){if(!this.zoomedByScrollbar){var c=a.dragger;c&&c.stop()}this.zoomedByScrollbar=!1;b.parseDates&&!b.equalSpacing?a.timeZoom(this.startTime,this.endTime):a.zoom(this.start,this.end)}this.zoomValueScrollbar(this.valueScrollbar)},updateTrendLines:function(){var a=this.trendLines,b;for(b=0;b<a.length;b++){var c=a[b],c=f.processObject(c,f.TrendLine,this.theme);a[b]=c;c.chart=this;c.id||(c.id="trendLineAuto"+b+"_"+(new Date).getTime());f.isString(c.valueAxis)&&(c.valueAxis=this.getValueAxisById(c.valueAxis));c.valueAxis||(c.valueAxis=this.valueAxes[0]);c.categoryAxis=this.categoryAxis}},countColumns:function(){var a=0,b=this.valueAxes.length,c=this.graphs.length,d,g,f=!1,e,l;for(l=0;l<b;l++){g=this.valueAxes[l];var k=g.stackType,m=0;if("100%"==k||"regular"==k)for(f=!1,e=0;e<c;e++)d=this.graphs[e],d.tcc=1,d.valueAxis==g&&"column"==d.type&&(!f&&d.stackable&&(a++,f=!0),(!d.stackable&&d.clustered||d.newStack&&0!==m)&&a++,d.columnIndex=a-1,d.clustered||(d.columnIndex=0),m++);if("none"==k||"3d"==k){f=!1;for(e=0;e<c;e++)d=this.graphs[e],d.valueAxis==g&&"column"==d.type&&(d.clustered?(d.tcc=1,d.newStack&&(a=0),d.hidden||(d.columnIndex=a,a++)):d.hidden||(f=!0,d.tcc=1,d.columnIndex=0));f&&0===a&&(a=1)}if("3d"==k){g=1;for(l=0;l<c;l++)d=this.graphs[l],d.newStack&&g++,d.depthCount=g,d.tcc=a;a=g}}return a},parseData:function(){f.AmSerialChart.base.parseData.call(this);this.parseSerialData(this.dataProvider)},getCategoryIndexByValue:function(a){var b=this.chartData,c;for(c=0;c<b.length;c++)if(b[c].category==a)return c},handleScrollbarZoom:function(a){this.zoomedByScrollbar=!0;this.zoom(a.start,a.end)},dispatchTimeZoomEvent:function(){if(this.drawGraphs&&(this.prevStartTime!=this.startTime||this.prevEndTime!=this.endTime)){var a={type:"zoomed"};a.startDate=new Date(this.startTime);a.endDate=new Date(this.endTime);a.startIndex=this.start;a.endIndex=this.end;this.startIndex=this.start;this.endIndex=this.end;this.startDate=a.startDate;this.endDate=a.endDate;this.prevStartTime=this.startTime;this.prevEndTime=this.endTime;var b=this.categoryAxis,c=f.extractPeriod(b.minPeriod).period,b=b.dateFormatsObject[c];a.startValue=f.formatDate(a.startDate,b,this);a.endValue=f.formatDate(a.endDate,b,this);a.chart=this;a.target=this;this.fire(a)}},dispatchIndexZoomEvent:function(){if(this.drawGraphs&&(this.prevStartIndex!=this.start||this.prevEndIndex!=this.end)){this.startIndex=this.start;this.endIndex=this.end;var a=this.chartData;if(f.ifArray(a)&&!isNaN(this.start)&&!isNaN(this.end)){var b={chart:this,target:this,type:"zoomed"};b.startIndex=this.start;b.endIndex=this.end;b.startValue=a[this.start].category;b.endValue=a[this.end].category;this.categoryAxis.parseDates&&(this.startTime=a[this.start].time,this.endTime=a[this.end].time,b.startDate=new Date(this.startTime),b.endDate=new Date(this.endTime));this.prevStartIndex=this.start;this.prevEndIndex=this.end;this.fire(b)}}},updateLegendValues:function(){this.legend&&this.legend.updateValues()},getClosestIndex:function(a,b,c,d,g,f){0>g&&(g=0);f>a.length-1&&(f=a.length-1);var e=g+Math.round((f-g)/2),l=a[e][b];return c==l?e:1>=f-g?d?g:Math.abs(a[g][b]-c)<Math.abs(a[f][b]-c)?g:f:c==l?e:c<l?this.getClosestIndex(a,b, -c,d,g,e):this.getClosestIndex(a,b,c,d,e,f)},zoomToIndexes:function(a,b){var c=this.chartData;if(c){var d=c.length;0<d&&(0>a&&(a=0),b>d-1&&(b=d-1),d=this.categoryAxis,d.parseDates&&!d.equalSpacing?this.zoom(c[a].time,this.getEndTime(c[b].time)):this.zoom(a,b))}},zoomToDates:function(a,b){var c=this.chartData;if(c)if(this.categoryAxis.equalSpacing){var d=this.getClosestIndex(c,"time",a.getTime(),!0,0,c.length);b=f.resetDateToMin(b,this.categoryAxis.minPeriod,1);c=this.getClosestIndex(c,"time",b.getTime(),!1,0,c.length);this.zoom(d,c)}else this.zoom(a.getTime(),b.getTime())},zoomToCategoryValues:function(a,b){this.chartData&&this.zoom(this.getCategoryIndexByValue(a),this.getCategoryIndexByValue(b))},formatPeriodString:function(a,b){if(b){b.periodDataItem={};b.periodPercentDataItem={};var c=["value","open","low","high","close"],d="value open low high close average sum count".split(" "),g=b.valueAxis,h=this.chartData,e=b.numberFormatter;e||(e=this.nf);for(var l=0;l<c.length;l++){for(var k=c[l],m=0,p=0,n=0,u=0,v,x,E,t,r,B,q,w,y,C,F=this.start;F<=this.end;F++){var D=h[F];if(D){var A=D.axes[g.id].graphs[b.id];if(A){if(A.values){var z=A.values[k],D=D.x.categoryAxis;if(this.rotate){if(0>D||D>A.graph.height)z=NaN}else if(0>D||D>A.graph.width)z=NaN;if(!isNaN(z)){isNaN(v)&&(v=z);x=z;if(isNaN(E)||E>z)E=z;if(isNaN(t)||t<z)t=z;r=f.getDecimals(m);D=f.getDecimals(z);m+=z;m=f.roundTo(m,Math.max(r,D));p++;r=m/p}}if(A.percents&&(A=A.percents[k],!isNaN(A))){isNaN(B)&&(B=A);q=A;if(isNaN(w)||w>A)w=A;if(isNaN(y)||y<A)y=A;C=f.getDecimals(n);z=f.getDecimals(A);n+=A;n=f.roundTo(n,Math.max(C,z));u++;C=n/u}}}}m={open:v,close:x,high:t,low:E,average:r,sum:m,count:p};n={open:B,close:q,high:y,low:w,average:C,sum:n,count:u};a=f.formatValue(a,m,d,e,k+"\\.",this.usePrefixes,this.prefixesOfSmallNumbers,this.prefixesOfBigNumbers);a=f.formatValue(a,n,d,this.pf,"percents\\."+k+"\\.");b.periodDataItem[k]=m;b.periodPercentDataItem[k]=n}}return a=f.cleanFromEmpty(a)},formatString:function(a,b,c){if(b){var d=b.graph;if(void 0!==a){if(-1!=a.indexOf("[[category]]")){var g=b.serialDataItem.category;if(this.categoryAxis.parseDates){var h=this.balloonDateFormat,e=this.chartCursor;e&&e.categoryBalloonDateFormat&&(h=e.categoryBalloonDateFormat);h=f.formatDate(g,h,this);-1!=h.indexOf("fff")&&(h=f.formatMilliseconds(h,g));g=h}a=a.replace(/\[\[category\]\]/g,String(g.replace("$","$$$")))}g=d.numberFormatter;g||(g=this.nf);h=b.graph.valueAxis;(e=h.duration)&&!isNaN(b.values.value)&&(e=f.formatDuration(b.values.value,e,"",h.durationUnits,h.maxInterval,g),a=a.replace(RegExp("\\[\\[value\\]\\]","g"),e));"date"==h.type&&(h=f.formatDate(new Date(b.values.value),d.dateFormat,this),e=RegExp("\\[\\[value\\]\\]","g"),a=a.replace(e,h),h=f.formatDate(new Date(b.values.open),d.dateFormat,this),e=RegExp("\\[\\[open\\]\\]","g"),a=a.replace(e,h));d="value open low high close total".split(" ");h=this.pf;a=f.formatValue(a,b.percents,d,h,"percents\\.");a=f.formatValue(a,b.values,d,g,"",this.usePrefixes,this.prefixesOfSmallNumbers,this.prefixesOfBigNumbers);a=f.formatValue(a,b.values,["percents"],h);-1!=a.indexOf("[[")&&(a=f.formatDataContextValue(a,b.dataContext));-1!=a.indexOf("[[")&&b.graph.customData&&(a=f.formatDataContextValue(a,b.graph.customData));a=f.AmSerialChart.base.formatString.call(this,a,b,c)}return a}},updateChartCursor:function(){f.AmSerialChart.base.updateChartCursor.call(this);var a=this.chartCursor,b=this.categoryAxis;if(a){var c=a.categoryBalloonAlpha,d=a.categoryBalloonColor,g=a.color;void 0===d&&(d=a.cursorColor);var h=a.valueZoomable,e=a.zoomable,l=a.valueLineEnabled;this.rotate?(a.vLineEnabled=l,a.hZoomEnabled=h,a.vZoomEnabled=e):(a.hLineEnabled=l,a.vZoomEnabled=h,a.hZoomEnabled=e);if(a.valueLineBalloonEnabled)for(l=0;l<this.valueAxes.length;l++)h=this.valueAxes[l],(e=h.balloon)||(e={}),e=f.extend(e,this.balloon,!0),e.fillColor=d,e.balloonColor=d,e.fillAlpha=c,e.borderColor=d,e.color=g,h.balloon=e;else for(e=0;e<this.valueAxes.length;e++)h=this.valueAxes[e],h.balloon&&(h.balloon=null);b&&(b.balloonTextFunction=a.categoryBalloonFunction,a.categoryLineAxis=b,b.balloonText=a.categoryBalloonText,a.categoryBalloonEnabled&&((e=b.balloon)||(e={}),e=f.extend(e,this.balloon,!0),e.fillColor=d,e.balloonColor=d,e.fillAlpha=c,e.borderColor=d,e.color=g,b.balloon=e),b.balloon&&(b.balloon.enabled=a.categoryBalloonEnabled))}},addChartScrollbar:function(a){f.callMethod("destroy",[this.chartScrollbar]);a&&(a.chart=this,this.listenTo(a,"zoomed",this.handleScrollbarZoom));this.rotate?void 0===a.width&&(a.width=a.scrollbarHeight):void 0===a.height&&(a.height=a.scrollbarHeight);a.gridAxis=this.categoryAxis;this.chartScrollbar=a},addValueScrollbar:function(a){f.callMethod("destroy",[this.valueScrollbar]);a&&(a.chart=this,this.listenTo(a,"zoomed",this.handleScrollbarValueZoom),this.listenTo(a,"zoomStarted",this.handleCursorZoomStarted));var b=a.scrollbarHeight;this.rotate?void 0===a.height&&(a.height=b):void 0===a.width&&(a.width=b);a.gridAxis||(a.gridAxis=this.valueAxes[0]);a.valueAxes=this.valueAxes;this.valueScrollbar=a},removeChartScrollbar:function(){f.callMethod("destroy",[this.chartScrollbar]);this.chartScrollbar=null},removeValueScrollbar:function(){f.callMethod("destroy",[this.valueScrollbar]);this.valueScrollbar=null},handleReleaseOutside:function(a){f.AmSerialChart.base.handleReleaseOutside.call(this,a);f.callMethod("handleReleaseOutside",[this.chartScrollbar,this.valueScrollbar])},update:function(){f.AmSerialChart.base.update.call(this);this.chartScrollbar&&this.chartScrollbar.update&&this.chartScrollbar.update();this.valueScrollbar&&this.valueScrollbar.update&&this.valueScrollbar.update()},processScrollbars:function(){f.AmSerialChart.base.processScrollbars.call(this);var a=this.valueScrollbar;a&&(a=f.processObject(a,f.ChartScrollbar,this.theme),a.id="valueScrollbar",this.addValueScrollbar(a))},handleValueAxisZoom:function(a){this.handleValueAxisZoomReal(a,this.valueAxes)},zoomOut:function(){f.AmSerialChart.base.zoomOut.call(this);this.zoom();this.syncGrid()},getNextItem:function(a){var b=a.index,c=this.chartData,d=a.graph;if(b+1<c.length)for(b+=1;b<c.length;b++)if(a=c[b])if(a=a.axes[d.valueAxis.id].graphs[d.id],!isNaN(a.y))return a},handleCursorZoomReal:function(a,b,c,d,g){var f=g.target,e,l;this.rotate?(isNaN(a)||isNaN(b)||this.relativeZoomValueAxes(this.valueAxes,a,b)&&this.updateAfterValueZoom(),f.vZoomEnabled&&(e=g.start,l=g.end)):(isNaN(c)||isNaN(d)||this.relativeZoomValueAxes(this.valueAxes,c,d)&&this.updateAfterValueZoom(),f.hZoomEnabled&&(e=g.start,l=g.end));isNaN(e)||isNaN(l)||(a=this.categoryAxis,a.parseDates&&!a.equalSpacing?this.zoomToDates(new Date(e),new Date(l)):this.zoomToIndexes(e,l))},handleCursorZoomStarted:function(){var a=this.valueAxes;if(a){var a=a[0],b=a.relativeStart,c=a.relativeEnd;a.reversed&&(b=1-a.relativeEnd,c=1-a.relativeStart);this.rotate?(this.startX0=b,this.endX0=c):(this.startY0=b,this.endY0=c)}this.categoryAxis&&(this.start0=this.start,this.end0=this.end,this.startTime0=this.startTime,this.endTime0=this.endTime)},fixCursor:function(){this.chartCursor&&this.chartCursor.fixPosition();this.prevCursorItem=null},handleCursorMove:function(a){f.AmSerialChart.base.handleCursorMove.call(this,a);var b=a.target,c=this.categoryAxis;if(a.panning)this.handleCursorHide(a);else if(this.chartData&&!b.isHidden){var d=this.graphs;if(d){var g;g=c.xToIndex(this.rotate?a.y:a.x);if(g=this.chartData[g]){var h,e,l,k;if(b.oneBalloonOnly&&b.valueBalloonsEnabled){var m=Infinity;for(h=d.length-1;0<=h;h--)if(e=d[h],e.balloon.enabled&&e.showBalloon&&!e.hidden){l=e.valueAxis.id;l=g.axes[l].graphs[e.id];if(b.showNextAvailable&&isNaN(l.y)&&(l=this.getNextItem(l),!l))continue;l=l.y;"top"==e.showBalloonAt&&(l=0);"bottom"==e.showBalloonAt&&(l=this.height);var p=b.mouseX,n=b.mouseY;l=this.rotate?Math.abs(p-l):Math.abs(n-l);l<m&&(m=l,k=e)}b.mostCloseGraph=k}if(this.prevCursorItem!=g||k!=this.prevMostCloseGraph){m=[];for(h=0;h<d.length;h++){e=d[h];l=e.valueAxis.id;l=g.axes[l].graphs[e.id];if(b.showNextAvailable&&isNaN(l.y)&&(l=this.getNextItem(l),!l&&e.balloon)){e.balloon.hide();continue}k&&e!=k?(e.showGraphBalloon(l,b.pointer,!1,b.graphBulletSize,b.graphBulletAlpha),e.balloon.hide(0)):b.valueBalloonsEnabled?(e.balloon.showBullet=b.bulletsEnabled,e.balloon.bulletSize=b.bulletSize/2,a.hideBalloons||(e.showGraphBalloon(l,b.pointer,!1,b.graphBulletSize,b.graphBulletAlpha),e.balloon.set&&m.push({balloon:e.balloon,y:e.balloon.pointToY}))):(e.currentDataItem=l,e.resizeBullet(l,b.graphBulletSize,b.graphBulletAlpha))}b.avoidBalloonOverlapping&&this.arrangeBalloons(m);this.prevCursorItem=g}this.prevMostCloseGraph=k}}c.showBalloon(a.x,a.y,b.categoryBalloonDateFormat,a.skip);this.updateLegendValues()}},handleCursorHide:function(a){f.AmSerialChart.base.handleCursorHide.call(this,a);a=this.categoryAxis;this.prevCursorItem=null;this.updateLegendValues();a&&a.hideBalloon();a=this.graphs;var b;for(b=0;b<a.length;b++)a[b].currentDataItem=null},handleCursorPanning:function(a){var b=a.target,c,d=a.deltaX,g=a.deltaY,h=a.delta2X,e=a.delta2Y;a=!1;if(this.rotate){isNaN(h)&&(h=d,a=!0);var l=this.endX0;c=this.startX0;var k=l-c,l=l-k*h,m=k;a||(m=0);a=f.fitToBounds(c-k*d,0,1-m)}else isNaN(e)&&(e=g,a=!0),l=this.endY0,c=this.startY0,k=l-c,l+=k*g,m=k,a||(m=0),a=f.fitToBounds(c+k*e,0,1-m);c=f.fitToBounds(l,m,1);var p;b.valueZoomable&&(p=this.relativeZoomValueAxes(this.valueAxes,a,c));var n;c=this.categoryAxis;this.rotate&&(d=g,h=e);a=!1;isNaN(h)&&(h=d,a=!0);if(b.zoomable&&(0<Math.abs(d)||0<Math.abs(h)))if(c.parseDates&&!c.equalSpacing){if(e=this.startTime0,g=this.endTime0,c=g-e,h*=c,k=this.firstTime,l=this.lastTime,m=c,a||(m=0),a=Math.round(f.fitToBounds(e-c*d,k,l-m)),h=Math.round(f.fitToBounds(g-h,k+m,l)),this.startTime!=a||this.endTime!=h)n={chart:this,target:b,type:"zoomed",start:a,end:h},this.skipZoomed=!0,b.fire(n),this.zoom(a,h),n=!0}else if(e=this.start0,g=this.end0,c=g-e,d=Math.round(c*d),h=Math.round(c*h),k=this.chartData.length-1,a||(c=0),a=f.fitToBounds(e-d,0,k-c),c=f.fitToBounds(g-h,c,k),this.start!=a||this.end!=c)this.skipZoomed=!0,b.fire({chart:this,target:b,type:"zoomed",start:a,end:c}),this.zoom(a,c),n=!0;!n&&p&&this.updateAfterValueZoom()},arrangeBalloons:function(a){var b=this.plotAreaHeight;a.sort(this.compareY);var c,d,f,h=this.plotAreaWidth,e=a.length;for(c=0;c<e;c++)d=a[c].balloon,d.setBounds(0,0,h,b),d.restorePrevious(),d.draw(),b=d.yPos-3;a.reverse();for(c=0;c<e;c++){d=a[c].balloon;var b=d.bottom,l=d.bottom-d.yPos;0<c&&b-l<f+3&&d.setBounds&&(d.setBounds(0,f+3,h,f+l+3),d.restorePrevious(),d.draw());d.set&&d.set.show();f=d.bottom}},compareY:function(a,b){return a.y<b.y?1:-1}})})();(function(){var f=window.AmCharts;f.Cuboid=f.Class({construct:function(a,b,c,d,f,h,e,l,k,m,p,n,u,v,x,E,t){this.set=a.set();this.container=a;this.h=Math.round(c);this.w=Math.round(b);this.dx=d;this.dy=f;this.colors=h;this.alpha=e;this.bwidth=l;this.bcolor=k;this.balpha=m;this.dashLength=v;this.topRadius=E;this.pattern=x;this.rotate=u;this.bcn=t;u?0>b&&0===p&&(p=180):0>c&&270==p&&(p=90);this.gradientRotation=p;0===d&&0===f&&(this.cornerRadius=n);this.draw()},draw:function(){var a=this.set;a.clear();var b=this.container,c=b.chart,d=this.w,g=this.h,h=this.dx,e=this.dy,l=this.colors,k=this.alpha,m=this.bwidth,p=this.bcolor,n=this.balpha,u=this.gradientRotation,v=this.cornerRadius,x=this.dashLength,E=this.pattern,t=this.topRadius,r=this.bcn,B=l,q=l;"object"==typeof l&&(B=l[0],q=l[l.length-1]);var w,y,C,F,D,A,z,L,M,Q=k;E&&(k=0);var G,H,I,J,K=this.rotate;if(0<Math.abs(h)||0<Math.abs(e))if(isNaN(t))z=q,q=f.adjustLuminosity(B,-.2),q=f.adjustLuminosity(B,-.2),w=f.polygon(b,[0,h,d+h,d,0],[0,e,e,0,0],q,k,1,p,0,u),0<n&&(M=f.line(b,[0,h,d+h],[0,e,e],p,n,m,x)),y=f.polygon(b,[0,0,d,d,0],[0,g,g,0,0],q,k,1,p,0,u),y.translate(h,e),0<n&&(C=f.line(b,[h,h],[e,e+g],p,n,m,x)),F=f.polygon(b,[0,0,h,h,0],[0,g,g+e,e,0],q,k,1,p,0,u),D=f.polygon(b,[d,d,d+h,d+h,d],[0,g,g+e,e,0],q,k,1,p,0,u),0<n&&(A=f.line(b,[d,d+h,d+h,d],[0,e,g+e,g],p,n,m,x)),q=f.adjustLuminosity(z,.2),z=f.polygon(b,[0,h,d+h,d,0],[g,g+e,g+e,g,g],q,k,1,p,0,u),0<n&&(L=f.line(b,[0,h,d+h],[g,g+e,g+e],p,n,m,x));else{var N,O,P;K?(N=g/2,q=h/2,P=g/2,O=d+h/2,H=Math.abs(g/2),G=Math.abs(h/2)):(q=d/2,N=e/2,O=d/2,P=g+e/2+1,G=Math.abs(d/2),H=Math.abs(e/2));I=G*t;J=H*t;.1<G&&.1<G&&(w=f.circle(b,G,B,k,m,p,n,!1,H),w.translate(q,N));.1<I&&.1<I&&(z=f.circle(b,I,f.adjustLuminosity(B,.5),k,m,p,n,!1,J),z.translate(O,P))}k=Q;1>Math.abs(g)&&(g=0);1>Math.abs(d)&&(d=0);!isNaN(t)&&(0<Math.abs(h)||0<Math.abs(e))?(l=[B],l={fill:l,stroke:p,"stroke-width":m,"stroke-opacity":n,"fill-opacity":k},K?(k="M0,0 L"+d+","+(g/2-g/2*t),m=" B",0<d&&(m=" A"),f.VML?(k+=m+Math.round(d- -I)+","+Math.round(g/2-J)+","+Math.round(d+I)+","+Math.round(g/2+J)+","+d+",0,"+d+","+g,k=k+(" L0,"+g)+(m+Math.round(-G)+","+Math.round(g/2-H)+","+Math.round(G)+","+Math.round(g/2+H)+",0,"+g+",0,0")):(k+="A"+I+","+J+",0,0,0,"+d+","+(g-g/2*(1-t))+"L0,"+g,k+="A"+G+","+H+",0,0,1,0,0"),G=90):(m=d/2-d/2*t,k="M0,0 L"+m+","+g,f.VML?(k="M0,0 L"+m+","+g,m=" B",0>g&&(m=" A"),k+=m+Math.round(d/2-I)+","+Math.round(g-J)+","+Math.round(d/2+I)+","+Math.round(g+J)+",0,"+g+","+d+","+g,k+=" L"+d+",0",k+=m+Math.round(d/ -2+G)+","+Math.round(H)+","+Math.round(d/2-G)+","+Math.round(-H)+","+d+",0,0,0"):(k+="A"+I+","+J+",0,0,0,"+(d-d/2*(1-t))+","+g+"L"+d+",0",k+="A"+G+","+H+",0,0,1,0,0"),G=180),b=b.path(k).attr(l),b.gradient("linearGradient",[B,f.adjustLuminosity(B,-.3),f.adjustLuminosity(B,-.3),B],G),K?b.translate(h/2,0):b.translate(0,e/2)):b=0===g?f.line(b,[0,d],[0,0],p,n,m,x):0===d?f.line(b,[0,0],[0,g],p,n,m,x):0<v?f.rect(b,d,g,l,k,m,p,n,v,u,x):f.polygon(b,[0,0,d,d,0],[0,g,g,0,0],l,k,m,p,n,u,!1,x);d=isNaN(t)?0>g?[w,M,y,C,F,D,A,z,L,b]:[z,L,y,C,F,D,w,M,A,b]:K?0<d?[w,b,z]:[z,b,w]:0>g?[w,b,z]:[z,b,w];f.setCN(c,b,r+"front");f.setCN(c,y,r+"back");f.setCN(c,z,r+"top");f.setCN(c,w,r+"bottom");f.setCN(c,F,r+"left");f.setCN(c,D,r+"right");for(w=0;w<d.length;w++)if(y=d[w])a.push(y),f.setCN(c,y,r+"element");E&&b.pattern(E,NaN,c.path)},width:function(a){isNaN(a)&&(a=0);this.w=Math.round(a);this.draw()},height:function(a){isNaN(a)&&(a=0);this.h=Math.round(a);this.draw()},animateHeight:function(a,b){var c=this;c.animationFinished=!1;c.easing=b;c.totalFrames=a*f.updateRate;c.rh=c.h;c.frame=0;c.height(1);setTimeout(function(){c.updateHeight.call(c)},1E3/f.updateRate)},updateHeight:function(){var a=this;a.frame++;var b=a.totalFrames;a.frame<=b?(b=a.easing(0,a.frame,1,a.rh-1,b),a.height(b),window.requestAnimationFrame?window.requestAnimationFrame(function(){a.updateHeight.call(a)}):setTimeout(function(){a.updateHeight.call(a)},1E3/f.updateRate)):(a.height(a.rh),a.animationFinished=!0)},animateWidth:function(a,b){var c=this;c.animationFinished=!1;c.easing=b;c.totalFrames=a*f.updateRate;c.rw=c.w;c.frame=0;c.width(1);setTimeout(function(){c.updateWidth.call(c)},1E3/f.updateRate)},updateWidth:function(){var a=this;a.frame++;var b=a.totalFrames;a.frame<=b?(b=a.easing(0,a.frame,1,a.rw-1,b),a.width(b),window.requestAnimationFrame?window.requestAnimationFrame(function(){a.updateWidth.call(a)}):setTimeout(function(){a.updateWidth.call(a)},1E3/f.updateRate)):(a.width(a.rw),a.animationFinished=!0)}})})();(function(){var f=window.AmCharts;f.CategoryAxis=f.Class({inherits:f.AxisBase,construct:function(a){this.cname="CategoryAxis";f.CategoryAxis.base.construct.call(this,a);this.minPeriod="DD";this.equalSpacing=this.parseDates=!1;this.position="bottom";this.startOnAxis=!1;this.gridPosition="middle";this.safeDistance=30;this.stickBalloonToCategory=!1;f.applyTheme(this,a,this.cname)},draw:function(){f.CategoryAxis.base.draw.call(this);this.generateDFObject();var a=this.chart.chartData;this.data=a;this.labelRotationR=this.labelRotation;this.type=null;if(f.ifArray(a)){var b,c=this.chart;"scrollbar"!=this.id?(f.setCN(c,this.set,"category-axis"),f.setCN(c,this.labelsSet,"category-axis"),f.setCN(c,this.axisLine.axisSet,"category-axis")):this.bcn=this.id+"-";var d=this.start,g=this.labelFrequency,h=0,e=this.end-d+1,l=this.gridCountR,k=this.showFirstLabel,m=this.showLastLabel,p,n="",n=f.extractPeriod(this.minPeriod),u=f.getPeriodDuration(n.period,n.count),v,x,E,t,r,B=this.rotate,q=this.firstDayOfWeek,w=this.boldPeriodBeginning;b=f.resetDateToMin(new Date(a[a.length-1].time+1.05*u),this.minPeriod,1,q).getTime();this.firstTime=c.firstTime;this.endTime>b&&(this.endTime=b);r=this.minorGridEnabled;x=this.gridAlpha;var y=0,C=0;if(this.widthField)for(b=this.start;b<=this.end;b++)if(t=this.data[b]){var F=Number(this.data[b].dataContext[this.widthField]);isNaN(F)||(y+=F,t.widthValue=F)}if(this.parseDates&&!this.equalSpacing)this.lastTime=a[a.length-1].time,this.maxTime=f.resetDateToMin(new Date(this.lastTime+1.05*u),this.minPeriod,1,q).getTime(),this.timeDifference=this.endTime-this.startTime,this.parseDatesDraw();else if(!this.parseDates){if(this.cellWidth=this.getStepWidth(e),e<l&&(l=e),h+=this.start,this.stepWidth=this.getStepWidth(e),0<l)for(q=Math.floor(e/l),t=this.chooseMinorFrequency(q),e=h,e/2==Math.round(e/2)&&e--,0>e&&(e=0),w=0,this.widthField&&(e=this.start,q=1),this.end-e+1>=this.autoRotateCount&&(this.labelRotationR=this.autoRotateAngle),b=e;b<=this.end+2;b++){l=!1;0<=b&&b<this.data.length?(v=this.data[b],n=v.category,l=v.forceShow):n="";if(r&&!isNaN(t))if(b/t==Math.round(b/t)||l)b/q==Math.round(b/q)||l||(this.gridAlpha=this.minorGridAlpha,n=void 0);else continue;else if(b/q!=Math.round(b/q)&&!l)continue;e=this.getCoordinate(b-h);l=0;"start"==this.gridPosition&&(e-=this.cellWidth/2,l=this.cellWidth/2);p=!0;E=l;"start"==this.tickPosition&&(E=0,p=!1,l=0);if(b==d&&!k||b==this.end&&!m)n=void 0;Math.round(w/g)!=w/g&&(n=void 0);w++;a=this.cellWidth;B&&(a=NaN,this.ignoreAxisWidth||!c.autoMargins)&&(a="right"==this.position?c.marginRight:c.marginLeft,a-=this.tickLength+10);this.labelFunction&&v&&(n=this.labelFunction(n,v,this));n=f.fixBrakes(n);u=!1;this.boldLabels&&(u=!0);b>this.end&&"start"==this.tickPosition&&(n=" ");this.rotate&&this.inside&&(l-=2);isNaN(v.widthValue)||(v.percentWidthValue=v.widthValue/y*100,a=this.rotate?this.height*v.widthValue/y:this.width*v.widthValue/y,e=C,C+=a,E=l=a/2);p=new this.axisItemRenderer(this,e,n,p,a,l,void 0,u,E,!1,v.labelColor,v.className);p.serialDataItem=v;this.pushAxisItem(p);this.gridAlpha=x}}else if(this.parseDates&&this.equalSpacing){h=this.start;this.startTime=this.data[this.start].time;this.endTime=this.data[this.end].time;this.timeDifference=this.endTime-this.startTime;b=this.choosePeriod(0);g=b.period;v=b.count;b=f.getPeriodDuration(g,v);b<u&&(g=n.period,v=n.count,b=u);x=g;"WW"==x&&(x="DD");this.currentDateFormat=this.dateFormatsObject[x];this.stepWidth=this.getStepWidth(e);l=Math.ceil(this.timeDifference/b)+1;n=f.resetDateToMin(new Date(this.startTime-b),g,v,q).getTime();this.cellWidth=this.getStepWidth(e);e=Math.round(n/b);d=-1;e/2==Math.round(e/2)&&(d=-2,n-=b);e=this.start;e/2==Math.round(e/2)&&e--;0>e&&(e=0);C=this.end+2;C>=this.data.length&&(C=this.data.length);a=!1;a=!k;this.previousPos=-1E3;20<this.labelRotationR&&(this.safeDistance=5);F=e;if(this.data[e].time!=f.resetDateToMin(new Date(this.data[e].time),g,v,q).getTime()){var u=0,D=n;for(b=e;b<C;b++)t=this.data[b].time,this.checkPeriodChange(g,v,t,D)&&(u++,2<=u&&(F=b,b=C),D=t)}r&&1<v&&(t=this.chooseMinorFrequency(v),f.getPeriodDuration(g,t));if(0<this.gridCountR)for(b=e;b<C;b++)if(t=this.data[b].time,this.checkPeriodChange(g,v,t,n)&&b>=F){e=this.getCoordinate(b-this.start);r=!1;this.nextPeriod[x]&&(r=this.checkPeriodChange(this.nextPeriod[x],1,t,n,x))&&f.resetDateToMin(new Date(t),this.nextPeriod[x],1,q).getTime()!=t&&(r=!1);u=!1;r&&this.markPeriodChange?(r=this.dateFormatsObject[this.nextPeriod[x]],u=!0):r=this.dateFormatsObject[x];n=f.formatDate(new Date(t),r,c);if(b==d&&!k||b==l&&!m)n=" ";a?a=!1:(w||(u=!1),e-this.previousPos>this.safeDistance*Math.cos(this.labelRotationR*Math.PI/180)&&(this.labelFunction&&(n=this.labelFunction(n,new Date(t),this,g,v,E)),this.boldLabels&&(u=!0),p=new this.axisItemRenderer(this,e,n,void 0,void 0,void 0,void 0,u),r=p.graphics(),this.pushAxisItem(p),r=r.getBBox().width,f.isModern||(r-=e),this.previousPos=e+r));E=n=t}}for(b=k=0;b<this.data.length;b++)if(t=this.data[b])this.parseDates&&!this.equalSpacing?(m=t.time,d=this.cellWidth,"MM"==this.minPeriod&&(d=864E5*f.daysInMonth(new Date(m))*this.stepWidth,t.cellWidth=d),m=Math.round((m-this.startTime)*this.stepWidth+d/2)):m=this.getCoordinate(b-h),t.x[this.id]=m;if(this.widthField)for(b=this.start;b<=this.end;b++)t=this.data[b],d=t.widthValue,t.percentWidthValue=d/y*100,this.rotate?(m=this.height*d/y/2+k,k=this.height*d/y+k):(m=this.width*d/y/2+k,k=this.width*d/y+k),t.x[this.id]=m;y=this.guides.length;for(b=0;b<y;b++)if(k=this.guides[b],q=q=q=r=d=NaN,m=k.above,k.toCategory&&(q=c.getCategoryIndexByValue(k.toCategory),isNaN(q)||(d=this.getCoordinate(q- -h),k.expand&&(d+=this.cellWidth/2),p=new this.axisItemRenderer(this,d,"",!0,NaN,NaN,k),this.pushAxisItem(p,m))),k.category&&(q=c.getCategoryIndexByValue(k.category),isNaN(q)||(r=this.getCoordinate(q-h),k.expand&&(r-=this.cellWidth/2),q=(d-r)/2,p=new this.axisItemRenderer(this,r,k.label,!0,NaN,q,k),this.pushAxisItem(p,m))),w=c.dataDateFormat,k.toDate&&(!w||k.toDate instanceof Date||(k.toDate=k.toDate.toString()+" |"),k.toDate=f.getDate(k.toDate,w),this.equalSpacing?(q=c.getClosestIndex(this.data,"time", -k.toDate.getTime(),!1,0,this.data.length-1),isNaN(q)||(d=this.getCoordinate(q-h))):d=(k.toDate.getTime()-this.startTime)*this.stepWidth,p=new this.axisItemRenderer(this,d,"",!0,NaN,NaN,k),this.pushAxisItem(p,m)),k.date&&(!w||k.date instanceof Date||(k.date=k.date.toString()+" |"),k.date=f.getDate(k.date,w),this.equalSpacing?(q=c.getClosestIndex(this.data,"time",k.date.getTime(),!1,0,this.data.length-1),isNaN(q)||(r=this.getCoordinate(q-h))):r=(k.date.getTime()-this.startTime)*this.stepWidth,q=(d- -r)/2,p=!0,k.toDate&&(p=!1),p="H"==this.orientation?new this.axisItemRenderer(this,r,k.label,p,2*q,NaN,k):new this.axisItemRenderer(this,r,k.label,!1,NaN,q,k),this.pushAxisItem(p,m)),p&&(q=p.label)&&this.addEventListeners(q,k),0<d||0<r){q=!1;if(this.rotate){if(d<this.height||r<this.height)q=!0}else if(d<this.width||r<this.width)q=!0;q&&(d=new this.guideFillRenderer(this,r,d,k),r=d.graphics(),this.pushAxisItem(d,m),k.graphics=r,r.index=b,this.addEventListeners(r,k))}if(c=c.chartCursor)B?c.fixHeight(this.cellWidth): -(c.fixWidth(this.cellWidth),c.fullWidth&&this.balloon&&(this.balloon.minWidth=this.cellWidth));this.previousHeight=A}this.axisCreated=!0;this.set.translate(this.x,this.y);this.labelsSet.translate(this.x,this.y);this.labelsSet.show();this.positionTitle();(B=this.axisLine.set)&&B.toFront();var A=this.getBBox().height;2<A-this.previousHeight&&this.autoWrap&&!this.parseDates&&(this.axisCreated=this.chart.marginsUpdated=!1)},xToIndex:function(a){var b=this.data,c=this.chart,d=c.rotate,g=this.stepWidth,h;if(this.parseDates&&!this.equalSpacing)a=this.startTime+Math.round(a/g)-this.minDuration()/2,h=c.getClosestIndex(b,"time",a,!1,this.start,this.end+1);else if(this.widthField)for(c=Infinity,g=this.start;g<=this.end;g++){var e=this.data[g];e&&(e=Math.abs(e.x[this.id]-a),e<c&&(c=e,h=g))}else this.startOnAxis||(a-=g/2),h=this.start+Math.round(a/g);h=f.fitToBounds(h,0,b.length-1);var l;b[h]&&(l=b[h].x[this.id]);d?l>this.height+1&&h--:l>this.width+1&&h--;0>l&&h++;return h=f.fitToBounds(h,0,b.length-1)}, -dateToCoordinate:function(a){return this.parseDates&&!this.equalSpacing?(a.getTime()-this.startTime)*this.stepWidth:this.parseDates&&this.equalSpacing?(a=this.chart.getClosestIndex(this.data,"time",a.getTime(),!1,0,this.data.length-1),this.getCoordinate(a-this.start)):NaN},categoryToCoordinate:function(a){if(this.chart){if(this.parseDates)return this.dateToCoordinate(new Date(a));a=this.chart.getCategoryIndexByValue(a);if(!isNaN(a))return this.getCoordinate(a-this.start)}else return NaN},coordinateToDate:function(a){return this.equalSpacing?(a=this.xToIndex(a),new Date(this.data[a].time)):new Date(this.startTime+a/this.stepWidth)},coordinateToValue:function(a){a=this.xToIndex(a);if(a=this.data[a])return this.parseDates?a.time:a.category},getCoordinate:function(a){a*=this.stepWidth;this.startOnAxis||(a+=this.stepWidth/2);return Math.round(a)},formatValue:function(a,b){b||(b=this.currentDateFormat);this.parseDates&&(a=f.formatDate(new Date(a),b,this.chart));return a},showBalloonAt:function(a,b){void 0===b&&(b=this.parseDates?this.dateToCoordinate(new Date(a)):this.categoryToCoordinate(a));return this.adjustBalloonCoordinate(b)},formatBalloonText:function(a,b,c){var d="",g="",h=this.chart,e=this.data[b];if(e)if(this.parseDates)d=f.formatDate(e.category,c,h),b=f.changeDate(new Date(e.category),this.minPeriod,1),g=f.formatDate(b,c,h),-1!=d.indexOf("fff")&&(d=f.formatMilliseconds(d,e.category),g=f.formatMilliseconds(g,b));else{var l;this.data[b+1]&&(l=this.data[b+1]);d=f.fixNewLines(e.category);l&&(g=f.fixNewLines(l.category))}a=a.replace(/\[\[category\]\]/g,String(d));return a=a.replace(/\[\[toCategory\]\]/g,String(g))},adjustBalloonCoordinate:function(a,b){var c=this.xToIndex(a),d=this.chart.chartCursor;if(this.stickBalloonToCategory){var f=this.data[c];f&&(a=f.x[this.id]);this.stickBalloonToStart&&(a-=this.cellWidth/2);var h=0;if(d){var e=d.limitToGraph;if(e){var l=e.valueAxis.id;e.hidden||(h=f.axes[l].graphs[e.id].y)}this.rotate?("left"==this.position?(e&&(h-=d.width),0<h&&(h=0)):0>h&&(h=0),d.fixHLine(a,h)):("top"==this.position?(e&&(h-=d.height),0<h&&(h=0)):0>h&&(h=0),d.fullWidth&&(a+=1),d.fixVLine(a,h))}}d&&!b&&(d.setIndex(c),this.parseDates&&d.setTimestamp(this.coordinateToDate(a).getTime()));return a}})})(); diff --git a/admin/src/main/resources/static/js/plugins/metisMenu/jquery.metisMenu.js b/admin/src/main/resources/static/js/plugins/metisMenu/jquery.metisMenu.js deleted file mode 100755 index 6f22effccf6efa30ec697bdcd497ec61d36f256a..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/metisMenu/jquery.metisMenu.js +++ /dev/null @@ -1,10 +0,0 @@ -/* - * metismenu - v2.0.2 - * A jQuery menu plugin - * https://github.com/onokumus/metisMenu - * - * Made by Osman Nuri Okumus - * Under MIT License - */ - -!function(a){"use strict";function b(){var a=document.createElement("mm"),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}function c(b){return this.each(function(){var c=a(this),d=c.data("mm"),f=a.extend({},e.DEFAULTS,c.data(),"object"==typeof b&&b);d||c.data("mm",d=new e(this,f)),"string"==typeof b&&d[b]()})}a.fn.emulateTransitionEnd=function(b){var c=!1,e=this;a(this).one("mmTransitionEnd",function(){c=!0});var f=function(){c||a(e).trigger(d.end)};return setTimeout(f,b),this};var d=b();d&&(a.event.special.mmTransitionEnd={bindType:d.end,delegateType:d.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}});var e=function(b,c){this.$element=a(b),this.options=a.extend({},e.DEFAULTS,c),this.transitioning=null,this.init()};e.TRANSITION_DURATION=350,e.DEFAULTS={toggle:!0,doubleTapToGo:!1,activeClass:"active"},e.prototype.init=function(){var b=this,c=this.options.activeClass;this.$element.find("li."+c).has("ul").children("ul").addClass("collapse in"),this.$element.find("li").not("."+c).has("ul").children("ul").addClass("collapse"),this.options.doubleTapToGo&&this.$element.find("li."+c).has("ul").children("a").addClass("doubleTapToGo"),this.$element.find("li").has("ul").children("a").on("click.metisMenu",function(d){var e=a(this),f=e.parent("li"),g=f.children("ul");return d.preventDefault(),f.hasClass(c)?b.hide(g):b.show(g),b.options.doubleTapToGo&&b.doubleTapToGo(e)&&"#"!==e.attr("href")&&""!==e.attr("href")?(d.stopPropagation(),void(document.location=e.attr("href"))):void 0})},e.prototype.doubleTapToGo=function(a){var b=this.$element;return a.hasClass("doubleTapToGo")?(a.removeClass("doubleTapToGo"),!0):a.parent().children("ul").length?(b.find(".doubleTapToGo").removeClass("doubleTapToGo"),a.addClass("doubleTapToGo"),!1):void 0},e.prototype.show=function(b){var c=this.options.activeClass,f=a(b),g=f.parent("li");if(!this.transitioning&&!f.hasClass("in")){g.addClass(c),this.options.toggle&&this.hide(g.siblings().children("ul.in")),f.removeClass("collapse").addClass("collapsing").height(0),this.transitioning=1;var h=function(){f.removeClass("collapsing").addClass("collapse in").height(""),this.transitioning=0};return d?void f.one("mmTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(e.TRANSITION_DURATION).height(f[0].scrollHeight):h.call(this)}},e.prototype.hide=function(b){var c=this.options.activeClass,f=a(b);if(!this.transitioning&&f.hasClass("in")){f.parent("li").removeClass(c),f.height(f.height())[0].offsetHeight,f.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var g=function(){this.transitioning=0,f.removeClass("collapsing").addClass("collapse")};return d?void f.height(0).one("mmTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(e.TRANSITION_DURATION):g.call(this)}};var f=a.fn.metisMenu;a.fn.metisMenu=c,a.fn.metisMenu.Constructor=e,a.fn.metisMenu.noConflict=function(){return a.fn.metisMenu=f,this}}(jQuery); \ No newline at end of file diff --git a/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.js b/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.js deleted file mode 100755 index 9c3b4dde266cbe590353cc6dfe12b1835e8b6b12..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.js +++ /dev/null @@ -1,470 +0,0 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * Version: 1.3.6 - * - */ -(function($) { - - $.fn.extend({ - slimScroll: function(options) { - - var defaults = { - - // width in pixels of the visible scroll area - width : 'auto', - - // height in pixels of the visible scroll area - height : '250px', - - // width in pixels of the scrollbar and rail - size : '7px', - - // scrollbar color, accepts any hex/color value - color: '#000', - - // scrollbar position - left/right - position : 'right', - - // distance in pixels between the side edge and the scrollbar - distance : '1px', - - // default scroll position on load - top / bottom / $('selector') - start : 'top', - - // sets scrollbar opacity - opacity : .4, - - // enables always-on mode for the scrollbar - alwaysVisible : false, - - // check if we should hide the scrollbar when user is hovering over - disableFadeOut : false, - - // sets visibility of the rail - railVisible : false, - - // sets rail color - railColor : '#333', - - // sets rail opacity - railOpacity : .2, - - // whether we should use jQuery UI Draggable to enable bar dragging - railDraggable : true, - - // defautlt CSS class of the slimscroll rail - railClass : 'slimScrollRail', - - // defautlt CSS class of the slimscroll bar - barClass : 'slimScrollBar', - - // defautlt CSS class of the slimscroll wrapper - wrapperClass : 'slimScrollDiv', - - // check if mousewheel should scroll the window if we reach top/bottom - allowPageScroll : false, - - // scroll amount applied to each mouse wheel step - wheelStep : 20, - - // scroll amount applied when user is using gestures - touchScrollStep : 200, - - // sets border radius - borderRadius: '7px', - - // sets border radius of the rail - railBorderRadius : '7px' - }; - - var o = $.extend(defaults, options); - - // do it for every element that matches selector - this.each(function(){ - - var isOverPanel, isOverBar, isDragg, queueHide, touchDif, - barHeight, percentScroll, lastScroll, - divS = '<div></div>', - minBarHeight = 30, - releaseScroll = false; - - // used in event handlers and for better minification - var me = $(this); - - // ensure we are not binding it again - if (me.parent().hasClass(o.wrapperClass)) - { - // start from last bar position - var offset = me.scrollTop(); - - // find bar and rail - bar = me.closest('.' + o.barClass); - rail = me.closest('.' + o.railClass); - - getBarHeight(); - - // check if we should scroll existing instance - if ($.isPlainObject(options)) - { - // Pass height: auto to an existing slimscroll object to force a resize after contents have changed - if ( 'height' in options && options.height == 'auto' ) { - me.parent().css('height', 'auto'); - me.css('height', 'auto'); - var height = me.parent().parent().height(); - me.parent().css('height', height); - me.css('height', height); - } - - if ('scrollTo' in options) - { - // jump to a static point - offset = parseInt(o.scrollTo); - } - else if ('scrollBy' in options) - { - // jump by value pixels - offset += parseInt(o.scrollBy); - } - else if ('destroy' in options) - { - // remove slimscroll elements - bar.remove(); - rail.remove(); - me.unwrap(); - return; - } - - // scroll content by the given offset - scrollContent(offset, false, true); - } - - return; - } - else if ($.isPlainObject(options)) - { - if ('destroy' in options) - { - return; - } - } - - // optionally set height to the parent's height - o.height = (o.height == 'auto') ? me.parent().height() : o.height; - - // wrap content - var wrapper = $(divS) - .addClass(o.wrapperClass) - .css({ - position: 'relative', - overflow: 'hidden', - width: o.width, - height: o.height - }); - - // update style for the div - me.css({ - overflow: 'hidden', - width: o.width, - height: o.height - }); - - // create scrollbar rail - var rail = $(divS) - .addClass(o.railClass) - .css({ - width: o.size, - height: '100%', - position: 'absolute', - top: 0, - display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none', - 'border-radius': o.railBorderRadius, - background: o.railColor, - opacity: o.railOpacity, - zIndex: 90 - }); - - // create scrollbar - var bar = $(divS) - .addClass(o.barClass) - .css({ - background: o.color, - width: o.size, - position: 'absolute', - top: 0, - opacity: o.opacity, - display: o.alwaysVisible ? 'block' : 'none', - 'border-radius' : o.borderRadius, - BorderRadius: o.borderRadius, - MozBorderRadius: o.borderRadius, - WebkitBorderRadius: o.borderRadius, - zIndex: 99 - }); - - // set position - var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance }; - rail.css(posCss); - bar.css(posCss); - - // wrap it - me.wrap(wrapper); - - // append to parent div - me.parent().append(bar); - me.parent().append(rail); - - // make it draggable and no longer dependent on the jqueryUI - if (o.railDraggable){ - bar.bind("mousedown", function(e) { - var $doc = $(document); - isDragg = true; - t = parseFloat(bar.css('top')); - pageY = e.pageY; - - $doc.bind("mousemove.slimscroll", function(e){ - currTop = t + e.pageY - pageY; - bar.css('top', currTop); - scrollContent(0, bar.position().top, false);// scroll content - }); - - $doc.bind("mouseup.slimscroll", function(e) { - isDragg = false;hideBar(); - $doc.unbind('.slimscroll'); - }); - return false; - }).bind("selectstart.slimscroll", function(e){ - e.stopPropagation(); - e.preventDefault(); - return false; - }); - } - - // on rail over - rail.hover(function(){ - showBar(); - }, function(){ - hideBar(); - }); - - // on bar over - bar.hover(function(){ - isOverBar = true; - }, function(){ - isOverBar = false; - }); - - // show on parent mouseover - me.hover(function(){ - isOverPanel = true; - showBar(); - hideBar(); - }, function(){ - isOverPanel = false; - hideBar(); - }); - - // support for mobile - me.bind('touchstart', function(e,b){ - if (e.originalEvent.touches.length) - { - // record where touch started - touchDif = e.originalEvent.touches[0].pageY; - } - }); - - me.bind('touchmove', function(e){ - // prevent scrolling the page if necessary - if(!releaseScroll) - { - e.originalEvent.preventDefault(); - } - if (e.originalEvent.touches.length) - { - // see how far user swiped - var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep; - // scroll content - scrollContent(diff, true); - touchDif = e.originalEvent.touches[0].pageY; - } - }); - - // set up initial height - getBarHeight(); - - // check start position - if (o.start === 'bottom') - { - // scroll content to bottom - bar.css({ top: me.outerHeight() - bar.outerHeight() }); - scrollContent(0, true); - } - else if (o.start !== 'top') - { - // assume jQuery selector - scrollContent($(o.start).position().top, null, true); - - // make sure bar stays hidden - if (!o.alwaysVisible) { bar.hide(); } - } - - // attach scroll events - attachWheel(this); - - function _onWheel(e) - { - // use mouse wheel only when mouse is over - if (!isOverPanel) { return; } - - var e = e || window.event; - - var delta = 0; - if (e.wheelDelta) { delta = -e.wheelDelta/120; } - if (e.detail) { delta = e.detail / 3; } - - var target = e.target || e.srcTarget || e.srcElement; - if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { - // scroll content - scrollContent(delta, true); - } - - // stop window scroll - if (e.preventDefault && !releaseScroll) { e.preventDefault(); } - if (!releaseScroll) { e.returnValue = false; } - } - - function scrollContent(y, isWheel, isJump) - { - releaseScroll = false; - var delta = y; - var maxTop = me.outerHeight() - bar.outerHeight(); - - if (isWheel) - { - // move bar with mouse wheel - delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight(); - - // move bar, make sure it doesn't go out - delta = Math.min(Math.max(delta, 0), maxTop); - - // if scrolling down, make sure a fractional change to the - // scroll position isn't rounded away when the scrollbar's CSS is set - // this flooring of delta would happened automatically when - // bar.css is set below, but we floor here for clarity - delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta); - - // scroll the scrollbar - bar.css({ top: delta + 'px' }); - } - - // calculate actual scroll amount - percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight()); - delta = percentScroll * (me[0].scrollHeight - me.outerHeight()); - - if (isJump) - { - delta = y; - var offsetTop = delta / me[0].scrollHeight * me.outerHeight(); - offsetTop = Math.min(Math.max(offsetTop, 0), maxTop); - bar.css({ top: offsetTop + 'px' }); - } - - // scroll content - me.scrollTop(delta); - - // fire scrolling event - me.trigger('slimscrolling', ~~delta); - - // ensure bar is visible - showBar(); - - // trigger hide when scroll is stopped - hideBar(); - } - - function attachWheel(target) - { - if (window.addEventListener) - { - target.addEventListener('DOMMouseScroll', _onWheel, false ); - target.addEventListener('mousewheel', _onWheel, false ); - } - else - { - document.attachEvent("onmousewheel", _onWheel) - } - } - - function getBarHeight() - { - // calculate scrollbar height and make sure it is not too small - barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight); - bar.css({ height: barHeight + 'px' }); - - // hide scrollbar if content is not long enough - var display = barHeight == me.outerHeight() ? 'none' : 'block'; - bar.css({ display: display }); - } - - function showBar() - { - // recalculate bar height - getBarHeight(); - clearTimeout(queueHide); - - // when bar reached top or bottom - if (percentScroll == ~~percentScroll) - { - //release wheel - releaseScroll = o.allowPageScroll; - - // publish approporiate event - if (lastScroll != percentScroll) - { - var msg = (~~percentScroll == 0) ? 'top' : 'bottom'; - me.trigger('slimscroll', msg); - } - } - else - { - releaseScroll = false; - } - lastScroll = percentScroll; - - // show only when required - if(barHeight >= me.outerHeight()) { - //allow window scroll - releaseScroll = true; - return; - } - bar.stop(true,true).fadeIn('fast'); - if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); } - } - - function hideBar() - { - // only hide when options allow it - if (!o.alwaysVisible) - { - queueHide = setTimeout(function(){ - if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg) - { - bar.fadeOut('slow'); - rail.fadeOut('slow'); - } - }, 1000); - } - } - - }); - - // maintain chainability - return this; - } - }); - - $.fn.extend({ - slimscroll: $.fn.slimScroll - }); - -})(jQuery); \ No newline at end of file diff --git a/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.min.js b/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.min.js deleted file mode 100755 index 7ecb25283652098ee59d270d36aad4daf973a121..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.min.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) - * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) - * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. - * - * Version: 1.3.6 - * - */ -(function(e){e.fn.extend({slimScroll:function(g){var a=e.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},g);this.each(function(){function v(d){if(r){d=d||window.event; - var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);e(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&m(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function m(d,e,g){k=!1;var f=d,h=b.outerHeight()-c.outerHeight();e&&(f=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),f=Math.min(Math.max(f,0),h),f=0<d?Math.ceil(f):Math.floor(f),c.css({top:f+"px"}));l=parseInt(c.css("top"))/(b.outerHeight()-c.outerHeight()); - f=l*(b[0].scrollHeight-b.outerHeight());g&&(f=d,d=f/b[0].scrollHeight*b.outerHeight(),d=Math.min(Math.max(d,0),h),c.css({top:d+"px"}));b.scrollTop(f);b.trigger("slimscrolling",~~f);w();p()}function x(){u=Math.max(b.outerHeight()/b[0].scrollHeight*b.outerHeight(),30);c.css({height:u+"px"});var a=u==b.outerHeight()?"none":"block";c.css({display:a})}function w(){x();clearTimeout(B);l==~~l?(k=a.allowPageScroll,C!=l&&b.trigger("slimscroll",0==~~l?"top":"bottom")):k=!1;C=l;u>=b.outerHeight()?k=!0:(c.stop(!0, - !0).fadeIn("fast"),a.railVisible&&h.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(B=setTimeout(function(){a.disableFadeOut&&r||y||z||(c.fadeOut("slow"),h.fadeOut("slow"))},1E3))}var r,y,z,B,A,u,l,C,k=!1,b=e(this);if(b.parent().hasClass(a.wrapperClass)){var n=b.scrollTop(),c=b.closest("."+a.barClass),h=b.closest("."+a.railClass);x();if(e.isPlainObject(g)){if("height"in g&&"auto"==g.height){b.parent().css("height","auto");b.css("height","auto");var q=b.parent().parent().height();b.parent().css("height", - q);b.css("height",q)}if("scrollTo"in g)n=parseInt(a.scrollTo);else if("scrollBy"in g)n+=parseInt(a.scrollBy);else if("destroy"in g){c.remove();h.remove();b.unwrap();return}m(n,!1,!0)}}else if(!(e.isPlainObject(g)&&"destroy"in g)){a.height="auto"==a.height?b.parent().height():a.height;n=e("<div></div>").addClass(a.wrapperClass).css({position:"relative",overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden",width:a.width,height:a.height});var h=e("<div></div>").addClass(a.railClass).css({width:a.size, - height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=e("<div></div>").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible?"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius,WebkitBorderRadius:a.borderRadius,zIndex:99}),q="right"==a.position? -{right:a.distance}:{left:a.distance};h.css(q);c.css(q);b.wrap(n);b.parent().append(c);b.parent().append(h);a.railDraggable&&c.bind("mousedown",function(a){var b=e(document);z=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);m(0,c.position().top,!1)});b.bind("mouseup.slimscroll",function(a){z=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll",function(a){a.stopPropagation();a.preventDefault();return!1}); - h.hover(function(){w()},function(){p()});c.hover(function(){y=!0},function(){y=!1});b.hover(function(){r=!0;w();p()},function(){r=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(A=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&&(m((A-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),A=b.originalEvent.touches[0].pageY)});x();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}), - m(0,!0)):"top"!==a.start&&(m(e(a.start).position().top,null,!0),a.alwaysVisible||c.hide());window.addEventListener?(this.addEventListener("DOMMouseScroll",v,!1),this.addEventListener("mousewheel",v,!1)):document.attachEvent("onmousewheel",v)}});return this}});e.fn.extend({slimscroll:e.fn.slimScroll})})(jQuery); \ No newline at end of file diff --git a/admin/src/main/resources/templates/fragments/components.html b/admin/src/main/resources/templates/fragments/components.html deleted file mode 100644 index 79d5263cad62f13fbb0f1c6895bc410b1159b6d2..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/fragments/components.html +++ /dev/null @@ -1,34 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head lang="en"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title>PDX Finder Admin Curator</title> -</head> -<body> - - <!-- ICONS COMPONENT --> - <div th:fragment="icons(title, image, link)" class="col-lg-2 col-md-3 col-sm-4 col-xs-6"> - - <div class="ibox"> - <div class="ibox-content" style="padding-bottom:10px;"> - <a href="#" th:href="${link}" > <img th:src="'images/icons/' + ${image}" class="icon"> </a> - <div class='text-navy pdx-singleLine' th:text="${title}"> RAW DATA </div> - </div> - </div> - </div> - - - - <!-- PROGRESS BAR COMPONENT --> - <li th:fragment="progressBar(num, desc, type, size)"> - <h3 class="no-margins" th:text="${num}"> ... </h3> - <small th:text="${desc}"> ... </small> - <div class="progress progress-mini"> - <div class="progress-bar" th:classappend="'progress-bar-'+ ${type}" th:style="'width:'+ ${size}">></div> - </div> - </li> - - - -</body> -</html> \ No newline at end of file diff --git a/admin/src/main/resources/templates/fragments/footer.html b/admin/src/main/resources/templates/fragments/footer.html deleted file mode 100644 index 710a7fcfc47fa7f03b097cd13273f1564ed20ff9..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/fragments/footer.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head lang="en"></head> -<body> - - <div th:fragment="footer"> - - <!-- Mainly scripts --> - <script th:src="@{/js/jquery-2.1.1.js}"></script> - <script th:src="@{/js/bootstrap.min.js}"></script> - <script th:src="@{/js/plugins/metisMenu/jquery.metisMenu.js}"></script> - <script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.min.js}"></script> - - <!-- Custom and plugin javascript --> - <script src="/js/pdxAdmin.js"></script> - - - <!-- Am Chart Dependencies Start --> - <link rel="stylesheet" href="/js/plugins/chart/export.css" type="text/css" media="all" /> - <script th:src="@{/js/plugins/chart/amcharts.js}"></script> - <script th:src="@{/js/plugins/chart/serial.js}"></script> - <script th:src="@{/js/plugins/chart/export.min.js}"></script> - <script th:src="@{/js/plugins/chart/light.js}"></script> - <!-- Am Chart Dependencies Ends --> - <script type="application/javascript" th:src="@{/js/plugins/chart/3dbar.js}"></script> - - </div> -</body> -</html> \ No newline at end of file diff --git a/admin/src/main/resources/templates/fragments/header.html b/admin/src/main/resources/templates/fragments/header.html deleted file mode 100644 index e1a9ddd00fd5c1b9bdd68781ea0cc3f927eefa6c..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/fragments/header.html +++ /dev/null @@ -1,20 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head lang="en" th:fragment="header"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title>PDX Finder Admin</title> - - <!--<link th:href="@{/webjars//bootstrap/css/bootstrap.css}" href="//cdn.jsdelivr.net/webjars/org.webjars/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet" media="screen"/> - <link th:href="@{/webjars//animate.css/animate.css}" href="//cdn.jsdelivr.net/webjars/org.webjars/animate.css/3.5.2/animate.css" rel="stylesheet" media="screen"/> - <link th:href="@{/webjars//font-awesome/css/font-awesome.css}" href="//cdn.jsdelivr.net/webjars/org.webjars/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" media="screen"/>--> - <link th:href="@{/css/bootstrap.css}" href="../static/css/bootstrap.css" rel="stylesheet"/> - <link th:href="@{/css/animate.css}" href="../static/css/animate.css" rel="stylesheet"/> - <link th:href="@{/css/font-awesome.css}" href="../static/css/font-awesome.css" rel="stylesheet"/> - <link th:href="@{/css/style.css}" href="../static/css/style.css" rel="stylesheet"/> - - -</head> -<body> - -</body> -</html> \ No newline at end of file diff --git a/admin/src/main/resources/templates/fragments/sidenav.html b/admin/src/main/resources/templates/fragments/sidenav.html deleted file mode 100644 index 6b70b600a6aa0f5ae85e80c73dc13dc8e6fc351c..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/fragments/sidenav.html +++ /dev/null @@ -1,75 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head lang="en"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title>PDX Finder Admin Curator</title> -</head> -<body> - - <nav th:fragment="side-navigation-menu" class="navbar-default navbar-static-side" role="navigation"> - - <div class="sidebar-collapse"> - <a class="close-canvas-menu"><i class="fa fa-times"></i></a> - <ul class="nav metismenu" id="side-menu"> - <li class="nav-header"> - <div class="dropdown profile-element"> <span> - <img alt="image" class="img-circle" src="images/profile_small.jpg" /> - </span> - <a data-toggle="dropdown" class="dropdown-toggle" href="#"> - <span class="clear"> <span class="block m-t-xs"> <strong class="font-bold">Nathalie Conte</strong> - </span> <span class="text-muted text-xs block">Bioinformatician <b class="caret"></b></span> </span> - </a> - </div> - <div class="logo-element"> - PDX+ - </div> - </li> - <li class="active"> - <a href="#"><i class="fa fa-th-large"></i> <span class="nav-label">Tool Box</span> <span class="fa arrow"></span></a> - <ul class="nav nav-second-level"> - <li class="active"><a href="#" class="active">Zooma Mappings</a></li> - <li><a href="#">PDX Finder Jira <span class="label label-primary pull-right">8</span></a></li> - <li><a href="#">Raw Data <span class="label label-primary pull-right">2</span></a></li> - <li><a href="#">Reports </a></li> - <li><a href="#">SOPs & Methods </a></li> - <li><a href="#">Finder </a></li> - <li><a href="#">Github </a></li> - <li><a href="#">Community Contacts </a></li> - </ul> - </li> - <li> <a href="#"><i class="fa fa-database"></i> <span class="nav-label">Manage IRCC Data</span></a> </li> - <li> <a href="#"><i class="fa fa-database"></i> <span class="nav-label">Manage JAX Data</span></a> </li> - <li> - <a href="#"><i class="fa fa-flask"></i> <span class="nav-label">PDX Models</span><span class="fa arrow"></span></a> - <ul class="nav nav-second-level collapse"> - <li><a href="#">Mouse Models <span class="label label-primary pull-right">Catalog</span></a></li> - <li><a href="#">Histopathological Data</a></li> - <li><a href="#">Host-Mouse Metadata</a></li> - <li><a href="#">Genomic Data <span class="label label-primary pull-right">435</span></a></li> - <li><a href="#">Chemotherapeutic</a></li> - <li><a href="#">Image Data</a></li> - </ul> - </li> - <li><a href="#"><i class="fa fa-pie-chart"></i> <span class="nav-label">PDX Model Request</span> </a></li> - <li><a href="#"><i class="fa fa-pie-chart"></i> <span class="nav-label">API Access Request</span> </a></li> - - <li> - <a href="#"><i class="fa fa-search-minus"></i> <span class="nav-label">User Search Report</span></a> - </li> - - <li class="landing_link"> - <a target="_blank" href="landing.html"><i class="fa fa-desktop"></i> <span class="nav-label">PDX Finder Website</span> </a> - </li> - <li class="special_link"> - <a href="package.html"><i class="fa fa-database"></i> <span class="nav-label">Neo4j Database</span></a> - </li> - </ul> - - </div> - - </nav> - - - -</body> -</html> \ No newline at end of file diff --git a/admin/src/main/resources/templates/fragments/topnav.html b/admin/src/main/resources/templates/fragments/topnav.html deleted file mode 100644 index 38c6e72a40d326d28c9092db7d1f5c5d1330ff96..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/fragments/topnav.html +++ /dev/null @@ -1,56 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head lang="en"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <title>PDX Finder Admin Curator</title> -</head> -<body> - - - <div th:fragment="top-navigation-menu" class="row border-bottom"> - - <nav class="navbar navbar-static-top white-bg" role="navigation" style="margin-bottom: 0"> - <div class="navbar-header"> - <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i> </a> - <form role="search" class="navbar-form-custom" action="search_results.html"> - <div class="form-group"> - <input type="text" placeholder="Search for PDX Models..." class="form-control" name="top-search" id="top-search"> - </div> - </form> - </div> - <ul class="nav navbar-top-links navbar-right"> - <li> - <span class="m-r-sm text-muted welcome-message">Welcome to PDX-Curator+ Admin</span> - </li> - <li class="dropdown"> - <a class="dropdown-toggle count-info" data-toggle="dropdown" href="#"> - <i class="fa fa-envelope"></i> <span class="label label-warning">6</span> - </a> - </li> - <li class="dropdown"> - <a class="dropdown-toggle count-info" data-toggle="dropdown" href="#"> - <i class="fa fa-bell"></i> <span class="label label-primary">8</span> - </a> - </li> - - - <li> - <a href="index.html"> - <i class="fa fa-sign-out"></i> Log out - </a> - </li> - <li> - <a class="right-sidebar-toggle"> - <i class="fa fa-tasks"></i> - </a> - </li> - </ul> - - </nav> - - </div> - - - -</body> -</html> \ No newline at end of file diff --git a/admin/src/main/resources/templates/index.html b/admin/src/main/resources/templates/index.html deleted file mode 100644 index f2767277f7ba3d77715ad8b2497a8b177ccd9f88..0000000000000000000000000000000000000000 --- a/admin/src/main/resources/templates/index.html +++ /dev/null @@ -1,128 +0,0 @@ -<!DOCTYPE html> -<html xmlns:th="http://www.thymeleaf.org"> -<head> - <!--/*/ <th:block th:include="fragments/header :: header"></th:block> /*/--> -</head> - -<body class="md-skin canvas-menu"> -<div id="wrapper"> - - <!-- Side Navigation menu here--> - <!--/*/ <th:block th:replace="fragments/sidenav :: side-navigation-menu"></th:block> /*/--> - - - - - <div id="page-wrapper" class="gray-bg"> - - <!-- Top Navigation Menu here --> - <!--/*/ <th:block th:replace="fragments/topnav :: top-navigation-menu"></th:block> /*/--> - - - <div class="wrapper wrapper-content animated fadeIn"> - <div class="p-w-md m-t-sm container"> - - - - - <div class="row" style="margin-top:-20px;"> - - - <div class="col-lg-12"> - <div class="ibox float-e-margins"> - <div class="ibox-content" > - - - <div> - <span class="pull-right text-right"> - <small>PDX Finder contains more than 800 PDX models from : <strong>JAX and IRCC</strong></small> - <br/> - All Models: 162,862 - </span> - <h3 class="font-bold no-margins"> - PDX Finder cancer by tissue - </h3> - <small>From all data sources.</small> - </div> - - <div class="m-t-sm"> - - <div class="row" style="margin-top:-10px;"> - <div class="col-md-8"> - <div id="chartdiv" style="width: 100%; height:280px;"></div> - </div> - <div class="col-md-4" style="margin-top:20px;"> - <ul class="stat-list m-t-lg"> - - <!--/*/ <th:block th:replace="fragments/components :: progressBar(num='2,346', desc='IRCC PDX Mouse Data', type='danger', size='30%')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: progressBar(num='4,422', desc='JAX PDX Mouse Data', type='info', size='36%')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: progressBar(num='2,912', desc='PDX Search last month', type='primary', size='80%')"></th:block> /*/--> - - </ul> - </div> - </div> - - </div> - - <div class="m-t-md"> - <small class="pull-right"> - <i class="fa fa-clock-o"> </i> - Updated on 30.07.2017 - </small> - <small> - <strong> PDX report summary :</strong> The report has been changed over time, and last month reached a level over 50,000 counts - </small> - </div> - - </div> - </div> - </div> - - </div> - - - - - <div class="row"> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='ZOOMA MAPPINGS ' , image='zoomaa.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='RAW DATA' , image='vms.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='PDXFinder JIRA' , image='jira2.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='REPORTS' , image='Reports-icon.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='SOPs & METHODS' , image='SOPs.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='FINDER' , image='finder.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='GITHUB' , image='github.jpg', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='COMMUNITY CONTACTS' , image='contact.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='SOPs & METHODS' , image='SOPs.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='FINDER' , image='finder.png', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='GITHUB' , image='github.jpg', link='')"></th:block> /*/--> - - <!--/*/ <th:block th:replace="fragments/components :: icons (title='COMMUNITY CONTACTS' , image='contact.png', link='')"></th:block> /*/--> - - </div> - - - </div> - </div> - </div> - -</div> - - - -<!--/*/ <th:block th:include="fragments/footer :: footer"></th:block> /*/--> - -</body> -</html> \ No newline at end of file diff --git a/data-model/pom.xml b/data-model/pom.xml index 35c7cdd72a98c1a960fcc5d353c026164ca4a329..4741d6583aa68d24a11a11b5858e52b9cadd80a7 100644 --- a/data-model/pom.xml +++ b/data-model/pom.xml @@ -3,6 +3,21 @@ 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> + <dependencies> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.2</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-embedded-driver</artifactId> + <version>3.1.20</version> + <scope>test</scope> + </dependency> + + </dependencies> <parent> <groupId>org.pdxfinder</groupId> @@ -14,20 +29,4 @@ <artifactId>data-model</artifactId> <packaging>jar</packaging> - <dependencies> - - <dependency> - <groupId>org.neo4j</groupId> - <artifactId>neo4j-ogm-embedded-driver</artifactId> - <scope>test</scope> - <version>2.1.1</version> - </dependency> - -<!-- <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-data-rest</artifactId> - </dependency>--> - - </dependencies> - </project> \ No newline at end of file diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/CurrentTreatment.java b/data-model/src/main/java/org/pdxfinder/graph/dao/CurrentTreatment.java index fabbd404c60f6c73720e10627eb30594f9f63ac1..d5601bc0051caa7864f5f8ed831080d4f4a59234 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/CurrentTreatment.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/CurrentTreatment.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; /* @@ -9,7 +10,7 @@ import org.neo4j.ogm.annotation.NodeEntity; @NodeEntity public class CurrentTreatment { - @GraphId + @Id @GeneratedValue private Long id; private String name; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/DataProjection.java b/data-model/src/main/java/org/pdxfinder/graph/dao/DataProjection.java index 33c35dc792c5019eca5ab97ea33581e5905d9c1c..a39208093accf6b8ed6555fb84a7f9810a060806 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/DataProjection.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/DataProjection.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; /* @@ -9,7 +10,7 @@ import org.neo4j.ogm.annotation.NodeEntity; @NodeEntity public class DataProjection { - @GraphId + @Id @GeneratedValue private Long id; private String label; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Drug.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Drug.java index b8912a04620b0f107343c02884d6e079d0203c65..59722b815d84c6dcb947d4aa9577182b58b2d705 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Drug.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Drug.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; /* @@ -18,7 +19,7 @@ public class Drug { * @param synonyms Synonyms of the drug */ - @GraphId + @Id @GeneratedValue private Long id; private String name; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalDataSource.java b/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalDataSource.java index e90314721650da3e2418e26889901c576194733d..de9b83a86810f64f537bf269abea6b6281e8686c 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalDataSource.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalDataSource.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; import java.util.Date; @@ -12,7 +13,7 @@ import java.util.List; @NodeEntity public class ExternalDataSource { - @GraphId + @Id @GeneratedValue private Long id; private String name; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalUrl.java b/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalUrl.java index 7ded1e7c4712551dca7a4264b711c881ffdeccb8..3d075a81593feec58eddc9749dd55b061ef0c164 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalUrl.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/ExternalUrl.java @@ -1,7 +1,8 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; /** @@ -10,7 +11,7 @@ import org.neo4j.ogm.annotation.NodeEntity; @NodeEntity public class ExternalUrl { - @GraphId + @Id @GeneratedValue private Long id; private String type; private String url; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Histology.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Histology.java index 30793938cdeee6a2b818ad89dc501091cb450e27..6405dfa2b3dcb722765b8ad25fa28f40c03bb843 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Histology.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Histology.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; @@ -13,7 +14,7 @@ import java.util.Set; @NodeEntity public class Histology { - @GraphId + @Id @GeneratedValue Long id; @Relationship(type = "HAS_IMAGE") diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Image.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Image.java index 47b5c0796ba993663764b864a2004dbd6b9f19d3..f9f9569df098c1d1fe8623c0bc4143ea4dc500a3 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Image.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Image.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import org.neo4j.ogm.annotation.NodeEntity; /** @@ -9,7 +10,7 @@ import org.neo4j.ogm.annotation.NodeEntity; @NodeEntity public class Image { - @GraphId + @Id @GeneratedValue Long id; private String url; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Marker.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Marker.java index 47604229d284539b48efa3950ba8668dd29a61e7..8fb821c00074c531b11c6476940229bb62b13240 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Marker.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Marker.java @@ -3,9 +3,9 @@ package org.pdxfinder.graph.dao; import org.apache.commons.lang3.StringUtils; import org.neo4j.ogm.annotation.Index; import org.neo4j.ogm.annotation.NodeEntity; + import javax.persistence.GeneratedValue; import javax.persistence.Id; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/MarkerAssociation.java b/data-model/src/main/java/org/pdxfinder/graph/dao/MarkerAssociation.java index b8c016558a27a2cf8387f7f33cec194a7cc8e1d7..55eaa9830523b9190f14fe8da050b76dba018b31 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/MarkerAssociation.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/MarkerAssociation.java @@ -24,7 +24,7 @@ public class MarkerAssociation { private String molecularDataString; private int dataPoints = 0; - private List<MolecularData> molecularDataList = new ArrayList<>(); + private List<MolecularData> molecularDataList; public MarkerAssociation() { molecularDataList = new ArrayList<>(); @@ -39,7 +39,8 @@ public class MarkerAssociation { } public void encodeMolecularData(){ - molecularDataString = new Gson().toJson(molecularDataList); + Gson gson = new Gson(); + molecularDataString = gson.toJson(molecularDataList); dataPoints = molecularDataList.size(); molecularDataList = Collections.emptyList(); } diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/OntologyTerm.java b/data-model/src/main/java/org/pdxfinder/graph/dao/OntologyTerm.java index 5f85bd4709b948cf257b02f6b39dbad6d1ff617c..f8b40110596a327607ec8def1e693e9be4a0f10d 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/OntologyTerm.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/OntologyTerm.java @@ -1,10 +1,11 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.Index; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import java.util.HashSet; import java.util.Set; @@ -14,7 +15,8 @@ import java.util.Set; @NodeEntity public class OntologyTerm { - @GraphId + @Id + @GeneratedValue private Long id; @Index diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/PatientSnapshot.java b/data-model/src/main/java/org/pdxfinder/graph/dao/PatientSnapshot.java index ad4e48ec882e79057c16e9525e0dd6cae310d74b..2baefc17c419ca18216001a6e945a11f5cd43bcd 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/PatientSnapshot.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/PatientSnapshot.java @@ -1,10 +1,12 @@ package org.pdxfinder.graph.dao; -import org.neo4j.cypher.internal.frontend.v2_3.SemanticDirection; -import org.neo4j.ogm.annotation.GraphId; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import java.util.HashSet; import java.util.Set; @@ -14,7 +16,8 @@ import java.util.Set; @NodeEntity public class PatientSnapshot { - @GraphId + @Id + @GeneratedValue private Long id; private String ageAtCollection; @@ -90,7 +93,7 @@ public class PatientSnapshot { if (ageInteger <= 23) { return "0-23 months"; } else { - return getAgeBin(ageInteger / 24); + return getAgeBin(ageInteger / 12); } } catch (Exception e){ @@ -246,4 +249,31 @@ public class PatientSnapshot { return String.format("[%s at age %s]", getPatient().getExternalId(), getAgeAtCollection()); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + PatientSnapshot that = (PatientSnapshot) o; + + return new EqualsBuilder() + .append(getAgeAtCollection(), that.getAgeAtCollection()) + .append(getDateAtCollection(), that.getDateAtCollection()) + .append(getCollectionEvent(), that.getCollectionEvent()) + .append(getElapsedTime(), that.getElapsedTime()) + .append(getPatient(), that.getPatient()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) + .append(getAgeAtCollection()) + .append(getDateAtCollection()) + .append(getCollectionEvent()) + .append(getElapsedTime()) + .append(getPatient()) + .toHashCode(); + } } diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Platform.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Platform.java index 2eeeeca81411ed220b43e2c54029a9b73718dc8d..6edd4b8223909266bd33c199a748735e572f2666 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Platform.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Platform.java @@ -1,9 +1,10 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import java.util.Set; /** @@ -12,7 +13,8 @@ import java.util.Set; @NodeEntity public class Platform { - @GraphId + @Id + @GeneratedValue private Long id; private String name; private String url; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/PlatformAssociation.java b/data-model/src/main/java/org/pdxfinder/graph/dao/PlatformAssociation.java index 5c9cce67f8aab28ca176a4302a424b444bc68a77..a7e8673490c7be16192e17292146433ed96f78f9 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/PlatformAssociation.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/PlatformAssociation.java @@ -1,16 +1,19 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + /** * Created by jmason on 21/07/2017. */ @NodeEntity public class PlatformAssociation { - @GraphId + @Id + @GeneratedValue Long id; private String exon; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/QualityAssurance.java b/data-model/src/main/java/org/pdxfinder/graph/dao/QualityAssurance.java index 2b91449c3219e709739724a08a6f7ad36deb1555..68511dee299d60e565b78159c73fe6660ef629c4 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/QualityAssurance.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/QualityAssurance.java @@ -1,7 +1,8 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /** * Created by jmason on 17/03/2017. @@ -9,7 +10,8 @@ import org.neo4j.ogm.annotation.NodeEntity; @NodeEntity public class QualityAssurance { - @GraphId + @Id + @GeneratedValue Long id; private String technology; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Response.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Response.java index 7ce6cfcdaa2b139d45e822d1d67435a71acab14c..f83084c44da12be2fa13044c69e0075f8199d35a 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Response.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Response.java @@ -1,8 +1,9 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /* * Created by csaba on 20/10/2017. @@ -10,7 +11,8 @@ import org.neo4j.ogm.annotation.Relationship; @NodeEntity public class Response { - @GraphId + @Id + @GeneratedValue private Long id; private String description; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Sample.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Sample.java index 2db4431f6a209de51a9fcca9d15ed33b0e420488..b05dba5224aeaa8e9d3b5526d8f8d27ba95f731d 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Sample.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Sample.java @@ -3,6 +3,7 @@ package org.pdxfinder.graph.dao; import org.apache.commons.collections4.CollectionUtils; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; + import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.util.HashSet; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/SampleToOntologyRelationship.java b/data-model/src/main/java/org/pdxfinder/graph/dao/SampleToOntologyRelationship.java index e0828412370639c9010cb73dbf58a847879d9b60..9586d443c0b63558727f567451c0fc9e8ff7968c 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/SampleToOntologyRelationship.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/SampleToOntologyRelationship.java @@ -2,6 +2,8 @@ package org.pdxfinder.graph.dao; import org.neo4j.ogm.annotation.*; import org.springframework.beans.factory.annotation.Autowired; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /* * Created by csaba on 16/11/2017. @@ -9,8 +11,9 @@ import org.springframework.beans.factory.annotation.Autowired; @RelationshipEntity(type="MAPPED_TO") public class SampleToOntologyRelationship { - @GraphId - private Long relationshipId; + @Id + @GeneratedValue + private Long id; @Property private String type; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Specimen.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Specimen.java index 5e4bbc559f489c1b6a854e1d93897e1998aab002..979d11f5d84eab841d2772db0f8535d1f9ca661c 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Specimen.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Specimen.java @@ -6,7 +6,6 @@ import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; import javax.persistence.GeneratedValue; import javax.persistence.Id; -import java.util.StringJoiner; /** * Created by jmason on 06/06/2017. diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/Treatment.java b/data-model/src/main/java/org/pdxfinder/graph/dao/Treatment.java index 21b6294fac92992ceb22764afee05eacc8345623..8a548a0d3a511780fc1a64881a8941d11266c39c 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/Treatment.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/Treatment.java @@ -1,8 +1,9 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /* * Created by csaba on 08/05/2019. @@ -11,7 +12,8 @@ import org.neo4j.ogm.annotation.Relationship; public class Treatment { - @GraphId + @Id + @GeneratedValue private Long id; private String name; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentComponent.java b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentComponent.java index a6ac343a3484b67ef01934680ad4eaf3c8c6d109..69b608713ff52b809c929cc822bdf78a878c656b 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentComponent.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentComponent.java @@ -1,8 +1,9 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /* * Created by csaba on 23/05/2018. @@ -10,7 +11,8 @@ import org.neo4j.ogm.annotation.Relationship; @NodeEntity public class TreatmentComponent { - @GraphId + @Id + @GeneratedValue private Long id; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentProtocol.java b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentProtocol.java index 2ba3c61adf66bd87b5f99dc0e76a055ef264aa94..d570d666c8dd932b8d30dfdec11a110b82ec11b8 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentProtocol.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentProtocol.java @@ -3,6 +3,7 @@ package org.pdxfinder.graph.dao; import org.apache.commons.lang3.StringUtils; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; + import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.util.ArrayList; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentSummary.java b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentSummary.java index 3a2ae4500a9f81743dcc0c63176b6d2dd791c188..2d9a03c03e0f1c05702ef62ab7296061b65b2bdb 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentSummary.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentSummary.java @@ -1,13 +1,12 @@ package org.pdxfinder.graph.dao; -import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.NodeEntity; import org.neo4j.ogm.annotation.Relationship; - +import javax.persistence.GeneratedValue; +import javax.persistence.Id; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; + /** * TreatmentSummary represents a summary of the application of a treatment protocol to a sample (either Human or Xenograft) @@ -16,7 +15,8 @@ import java.util.Set; @NodeEntity public class TreatmentSummary { - @GraphId + @Id + @GeneratedValue Long id; //url to a page that describes the treatment String url; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentToOntologyRelationship.java b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentToOntologyRelationship.java index 04aa63cf87ec8bd9f2d74f82e183662197552348..afe5566f3258bbfc4cb38223a7e7fecd001ab993 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentToOntologyRelationship.java +++ b/data-model/src/main/java/org/pdxfinder/graph/dao/TreatmentToOntologyRelationship.java @@ -1,6 +1,8 @@ package org.pdxfinder.graph.dao; import org.neo4j.ogm.annotation.*; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; /* * Created by csaba on 08/05/2019. @@ -8,8 +10,9 @@ import org.neo4j.ogm.annotation.*; @RelationshipEntity(type="MAPPED_TO") public class TreatmentToOntologyRelationship { - @GraphId - private Long relationshipId; + @Id + @GeneratedValue + private Long id; @Property private String type; diff --git a/data-model/src/main/java/org/pdxfinder/graph/dao/ValidationTechniques.java b/data-model/src/main/java/org/pdxfinder/graph/dao/ValidationTechniques.java deleted file mode 100644 index 2f8f4a0556f48b0efc20b31a1e619bc4a3b9289e..0000000000000000000000000000000000000000 --- a/data-model/src/main/java/org/pdxfinder/graph/dao/ValidationTechniques.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.pdxfinder.graph.dao; - -/** - * Created by jmason on 06/06/2017. - */ -public enum ValidationTechniques { - NOT_SPECIFIED("Not specified"), - FINGERPRINT("Fingerprint"), - FINGERPRINT_HISTOLOGY("Histology/STR"), - HISTOLOGY("Histology"), - HEALTH_CHECK("Health-check"); - - private String technique; - - private ValidationTechniques(String s) { - technique = s; - } - - public String getTechnique() { - return technique; - } - - -} diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/DataProjectionRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/DataProjectionRepository.java index f374f18228a723bd2a4880a860b57898f1dffcd3..0a321c6e3abbbac90ec2206100215c59a7beeef2 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/DataProjectionRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/DataProjectionRepository.java @@ -7,7 +7,6 @@ import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.Set; /* * Created by csaba on 09/03/2018. @@ -18,33 +17,4 @@ public interface DataProjectionRepository extends Neo4jRepository<DataProjection @Query("MATCH (dp:DataProjection) WHERE dp.label = {label} return dp ") DataProjection findByLabel(@Param("label") String label); - - - - - - - //VALIDATION QUERIES - - //find nodes that are not linked to anything - @Query("MATCH (n) WHERE NOT (n)--() RETURN n") - Set<Object> findUnlinkedNodes(); - - - //find patients that have multiple treatment summaries - @Query("MATCH (p:Patient)--(ps:PatientSnapshot)--(ts1:TreatmentSummary) " + - "WITH p, ps, ts1 " + - "MATCH (ps)--(ts2:TreatmentSummary) " + - "WHERE ts1 <> ts2 " + - "RETURN p") - Set<Object> findPatientsWithMultipleTreatmentSummaries(); - - - @Query("MATCH (pl:Platform) " + - "WHERE NOT exists(pl.url) " + - "OR pl.url = \"\" " + - "RETURN pl") - Set<Object> findPlatformsWithoutUrl(); - - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/DrugRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/DrugRepository.java deleted file mode 100644 index db9a7aa216e597ee69d508eaaa7971d0377ce902..0000000000000000000000000000000000000000 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/DrugRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.pdxfinder.graph.repositories; - -import org.neo4j.ogm.model.Result; -import org.pdxfinder.graph.dao.Drug; -import org.pdxfinder.graph.dao.ModelCreation; -import org.springframework.data.neo4j.annotation.Query; -import org.springframework.data.neo4j.repository.Neo4jRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.stereotype.Repository; - -import java.util.List; -import java.util.Set; - -/* - * Created by csaba on 23/05/2018. - */ -@Repository -public interface DrugRepository extends Neo4jRepository<Drug, Long> { - - @Query("MATCH (d:Drug) RETURN DISTINCT d.name") - List<String> findDistinctDrugNames(); - - - @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:TREATMENT]-(drug:Drug) " + - "RETURN drug.name AS drug_name, COUNT(DISTINCT mod.sourcePdxId) as model_count " + - "ORDER BY model_count DESC") - Result countModelsByDrug(); - - @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:DRUG]-(drug:Drug) " + - "WHERE tc.type = {type} " + - "RETURN drug.name AS drug_name, COUNT(DISTINCT mod.sourcePdxId) as model_count " + - "ORDER BY model_count DESC") - Result countModelsByDrugAndComponentType(@Param("type") String type); - - - -} diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/ExternalUrlRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/ExternalUrlRepository.java index 7df0046fd1862e723e3a89b2b19bf531461338c3..211341ac93d49b350ab58116610afd5e4559f644 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/ExternalUrlRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/ExternalUrlRepository.java @@ -5,18 +5,10 @@ import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; -import java.util.List; - public interface ExternalUrlRepository extends PagingAndSortingRepository<ExternalUrl, Long> { @Query("MATCH (u:ExternalUrl) WHERE u.type = {type} AND u.url = {url} RETURN u") ExternalUrl findByTypeAndUrl(@Param("type") String type, @Param("url") String url); - @Query("MATCH (exturl:ExternalUrl) RETURN DISTINCT exturl.type ORDER BY exturl.type") - List<String> findAllTypes(); - - @Query("MATCH (exturl:ExternalUrl) RETURN DISTINCT exturl.url ORDER BY exturl.url") - List<String> findAllUrls(); - } \ No newline at end of file diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/HostStrainRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/HostStrainRepository.java index 56f08947e1a8a4e723b00c40fd6911d304c6b7fe..3e6a84e652a36c27173ec71002c8643499acac66 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/HostStrainRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/HostStrainRepository.java @@ -18,7 +18,4 @@ public interface HostStrainRepository extends PagingAndSortingRepository<HostStr @Query("MATCH (t:HostStrain) WHERE t.name = {name} RETURN t") HostStrain findByName(@Param("name") String name); - @Query("MATCH (t:HostStrain) WHERE t.name = {name} AND t.symbol = {symbol} RETURN t") - HostStrain findByNameAndSymbol(@Param("name") String name, @Param("symbol") String symbol); - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerAssociationRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerAssociationRepository.java index 0320342fdd7ce39134798c579ec59f56a6c8e973..cc3db8f882e2b29c2bc7590f230c1c013d03d16c 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerAssociationRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerAssociationRepository.java @@ -7,7 +7,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; import java.util.Set; /** @@ -16,26 +15,9 @@ import java.util.Set; @Repository public interface MarkerAssociationRepository extends PagingAndSortingRepository<MarkerAssociation, Long>{ - //TODO: Verify cypher - @Query("MATCH (n:MarkerAssociation)-[]-(m:Marker) where n.description = {type} and m.hgncSymbol={symbol} return n") - MarkerAssociation findByTypeAndMarkerSymbol(@Param("type") String type, @Param("symbol") String symbol); - - @Query("MATCH (n:MarkerAssociation)-[]-(m:Marker) where n.description = {type} and m.name={name} return n") - MarkerAssociation findByTypeAndMarkerName(@Param("type") String type, @Param("name") String name); - @Query("MATCH (mc:MolecularCharacterization)--(ma:MarkerAssociation) WHERE id(mc) = {mc} RETURN ma") Set<MarkerAssociation> findMutationByMolChar(@Param("mc") MolecularCharacterization mc); @Query("MATCH (mc:MolecularCharacterization)--(ma:MarkerAssociation) WHERE id(mc) = {mc} RETURN ma") Set<MarkerAssociation> findByMolChar(@Param("mc") MolecularCharacterization mc); - - @Query("MATCH (mc:MolecularCharacterization)-[awr:ASSOCIATED_WITH]-(ma:MarkerAssociation) " + - "WHERE ID(mc) = {id} " + - "RETURN count(ma)") - int getMarkerAssociationCountByMolCharId(@Param("id") Long id); - - @Query("MATCH (mc:MolecularCharacterization)-[awr:ASSOCIATED_WITH]-(ma:MarkerAssociation)-[mr:MARKER]-(m:Marker) " + - "WHERE ID(mc) = {id} " + - "RETURN ma, mr, m SKIP {from} LIMIT {to}") - List<MarkerAssociation> findAssociationsByMolCharIdFromTo(@Param("id") Long id, @Param("from") int from, @Param("to") int to); } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerRepository.java index e68c76ede8f7590622b22c91bfe05a59922cd2bb..0b1a7b624e5df760579be393386d5d19d217fa50 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/MarkerRepository.java @@ -1,17 +1,14 @@ package org.pdxfinder.graph.repositories; -import org.neo4j.ogm.model.Result; import org.pdxfinder.graph.dao.Marker; -import org.pdxfinder.graph.dao.MarkerAssociation; -import org.pdxfinder.graph.queryresults.MutatedMarkerData; + import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.Collection; -import java.util.List; -import java.util.Set; + /** * Interface for Markers @@ -24,52 +21,17 @@ public interface MarkerRepository extends PagingAndSortingRepository<Marker, Lon @Query("MATCH (t:Marker) WHERE t.name = {name} RETURN t") Marker findByName(@Param("name") String name); - - @Query("MATCH (t:Marker) WHERE t.ensembleId = {id} RETURN t") - Marker findByEnsemblId(@Param("id") String id); @Query("MATCH (t:Marker) WHERE t.ncbiGeneId = {id} return t") Marker findByNcbiGeneId(@Param("id") String id); - @Query("MATCH (m:Marker) RETURN m") - Collection<Marker> findAllMarkers(); - @Query("MATCH (m:Marker) RETURN count(m)") Integer countAllMarkers(); - @Query("MATCH (m:Marker) " + "RETURN m") Collection<Marker> findAllHumanMarkers(); - @Query("MATCH (s:Sample)--(:MolecularCharacterization)--(:MarkerAssociation)--(m:Marker) WHERE s.sourceSampleId = {sampleId} return m") - Collection<Marker> findAllBySampleId(@Param("sampleId") String sampleId); - - @Query("MATCH (ma:MarkerAssociation)--(m:Marker) WHERE id(ma) = {ma} RETURN m") - Marker findByMarkerAssociation(@Param("ma") MarkerAssociation ma); - - - - @Query("MATCH (mod:ModelCreation)--(spec:Specimen)--(msamp:Sample)--(molchar:MolecularCharacterization)-->(mAss:MarkerAssociation)--(marker:Marker) " + - "RETURN marker.hgncSymbol AS gene_name, COUNT(DISTINCT mod.sourcePdxId) as number_of_models " + - "ORDER BY number_of_models DESC") - List<MutatedMarkerData> countModelsByMarker(); - - - @Query("MATCH (m:Marker) WHERE {synonym} IN m.aliasSymbols RETURN m") - List<Marker> findBySynonym(@Param("synonym") String synonym); - - @Query("MATCH (m:Marker) WHERE {synonym} IN m.prevSymbols RETURN m") - List<Marker> findByPrevSymbol(@Param("synonym") String synonym); - - @Query("MATCH (m:Marker) WHERE NOT (m)--() DELETE m") - void deleteMarkersWithoutRelationships(); - - @Query("MATCH (mc:MolecularCharacterization)-[awr:ASSOCIATED_WITH]-(ma:MarkerAssociation) " + - "WHERE ID(mc) = {id} " + - "RETURN DISTINCT m") - Set<Marker> findDistinctByMolCharId(@Param("id") Long id); - @Query("MATCH (m:Marker) return count(m)") int getMarkerCount(); diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/ModelCreationRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/ModelCreationRepository.java index c55eb3c260d24b1475fd2d0db0d7fb52ddcc6b72..54837b1ddfdcedca517acc3f6b8653559c5a6de5 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/ModelCreationRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/ModelCreationRepository.java @@ -128,56 +128,6 @@ public interface ModelCreationRepository extends Neo4jRepository<ModelCreation, Collection<ModelCreation> findAllModelsPlatforms(); - - @Query("MATCH (mc:ModelCreation)--(psamp:Sample)-[char:CHARACTERIZED_BY]-(molch:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) " + - " WHERE mc.dataSource = {dataSource} " + - " AND mc.sourcePdxId = {modelId} " + - "WITH mc, psamp, char, molch, assoc, mAss, aw, m " + - "MATCH (molch)-[pu:PLATFORM_USED]-(pl:Platform) " + - - " WHERE (pl.name = {tech} OR {tech} = '' ) " + - - " OR toLower(m.hgncSymbol) CONTAINS toLower({search}) " + - " OR any( property in keys(mAss) where toLower(mAss[property]) CONTAINS toLower({search}) ) " + - " RETURN count(*) ") - Integer variationCountByDataSourceAndPdxIdAndPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("search") String search); - - - @Query("MATCH (mc:ModelCreation)--(psamp:Sample)-[char:CHARACTERIZED_BY]-(molch:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) " + - - " WHERE mc.dataSource = {dataSource} " + - " AND mc.sourcePdxId = {modelId} " + - "WITH mc, psamp, char, molch, assoc, mAss, aw, m " + - "MATCH (molch)-[pu:PLATFORM_USED]-(pl:Platform) " + - - " WHERE (pl.name = {tech} OR {tech} = '' ) " + - - - " OR toLower(m.hgncSymbol) CONTAINS toLower({search})" + - " OR any( property in keys(mAss) where toLower(mAss[property]) CONTAINS toLower({search}) ) " + - - " RETURN mc,psamp,char,molch,mAss,m, pu, pl SKIP {skip} LIMIT {lim} ") - ModelCreation findVariationBySourcePdxIdAndPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("search") String search, - @Param("skip") int skip, - @Param("lim") int lim); - - @Query("MATCH (mc)-[msr:MODEL_SAMPLE_RELATION]-(s:Sample)-[cbr:CHARACTERIZED_BY]-(molChar:MolecularCharacterization)-[pur:PLATFORM_USED]-(p:Platform) " + - "WHERE mc.sourcePdxId={sourcePdxId} AND p.name={platform} AND mc.dataSource = {dataSource} " + - "WITH mc, msr, s, cbr, molChar, pur, p " + - - "OPTIONAL MATCH (molChar)-[assW:ASSOCIATED_WITH]-(mAss:MarkerAssociation) " + - "RETURN count(mAss) ") - Integer countMarkerAssociationBySourcePdxId(@Param("sourcePdxId") String sourcePdxId, - @Param("dataSource") String dataSource, - @Param("platform") String platform); - - @Query("MATCH (model:ModelCreation)--(s:Sample)--(molch:MolecularCharacterization) " + "WHERE id(molch) = {mc} " + "RETURN model") @@ -208,19 +158,21 @@ public interface ModelCreationRepository extends Neo4jRepository<ModelCreation, List<ModelCreation> findModelPlatformSampleByDS(@Param("dataSource") String dataSource); - @Query("MATCH (mod:ModelCreation) WHERE toLower(mod.dataSource) = toLower({dataSource}) and mod.sourcePdxId = {modelId} " + + @Query("MATCH (mod:ModelCreation) WHERE toLower(mod.dataSource) = toLower({dataSource}) " + "WITH mod " + - "OPTIONAL MATCH (mod)-[iir:IMPLANTED_IN]-(psamp:Sample)-[cbr:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation) " + + "MATCH (mod)--(samp:Sample)-[cbr:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation) " + "WHERE mc.type = {type} "+ - "WITH mod, iir, psamp, cbr, mc, assoc, mAss " + + "WITH mod, samp, cbr, mc, assoc, mAss " + + "OPTIONAL MATCH (mod)-[iir:IMPLANTED_IN]-(psamp:Sample) " + + "WITH iir, psamp, mod, samp, cbr, mc, assoc, mAss " + "OPTIONAL MATCH (mod)-[spr:SPECIMENS]-(sp:Specimen)-[sfr:SAMPLED_FROM]-(s:Sample)-[cbr2:CHARACTERIZED_BY]-(mc2:MolecularCharacterization)-[assoc2:ASSOCIATED_WITH]->(mAss2:MarkerAssociation) " + "WHERE mc2.type = {type} "+ - "WITH mod, iir, psamp, spr, sp, sfr, s, cbr, mc, mc2, cbr2, assoc, mAss, assoc2, mAss2 " + + "WITH iir, psamp, mod, samp, spr, sp, sfr, s, cbr, mc, mc2, cbr2, assoc, mAss, assoc2, mAss2 " + "OPTIONAL MATCH (sp)-[hsr:HOST_STRAIN]-(hs:HostStrain) " + "OPTIONAL MATCH (mc)-[pur:PLATFORM_USED]-(pl:Platform) " + "OPTIONAL MATCH (mc2)-[pur2:PLATFORM_USED]-(pl2:Platform) " + - "RETURN mod, iir, psamp, spr, sp, sfr, s, cbr, mc, mc2, cbr2, pur, pl, pur2, pl2, assoc, mAss, assoc2, mAss2, hsr, hs ") - ModelCreation findModelWithMolecularDataByDSAndIdAndMolcharType(@Param("dataSource") String dataSource, @Param("modelId") String modelId, @Param("type") String type); + "RETURN mod, iir, psamp, samp, spr, sp, sfr, s, cbr, mc, mc2, cbr2, pur, pl, pur2, pl2, assoc, mAss, assoc2, mAss2, hsr, hs ") + List<ModelCreation> findModelsWithMolecularDataByDSAndMolcharType(@Param("dataSource") String dataSource, @Param("type") String type); @Query("MATCH (mod:ModelCreation) WHERE toLower(mod.dataSource) = toLower({dataSource}) " + "WITH mod SKIP {from} LIMIT {to}" + @@ -259,10 +211,6 @@ public interface ModelCreationRepository extends Neo4jRepository<ModelCreation, "RETURN model, spr, sp, hsr, hs, sfr, s, psamp, ir, cbr, mc, pur, pl, cbr2, mc2, pur2, pl2") ModelCreation findBySourcePdxIdAndDataSourceWithSamplesAndSpecimensAndHostStrain(@Param("modelId") String modelId, @Param("dataSource") String dataSource); - @Query("CREATE INDEX ON :ModelCreation(dataSource, sourcePdxId)") - void createIndex(); - - @Query("MATCH (model:ModelCreation)-[msr:MODEL_SAMPLE_RELATION]-(samp:Sample)-[cby:CHARACTERIZED_BY]-(molchar:MolecularCharacterization)-[asw:ASSOCIATED_WITH]-(massoc:MarkerAssociation)-[mark:MARKER]-(marker:Marker) WHERE molchar.type={molcharType} " + "RETURN model, msr, samp, cby, molchar, asw, massoc, mark, marker") List<ModelCreation> findByMolcharType(@Param("molcharType") String molcharType); @@ -272,6 +220,19 @@ public interface ModelCreationRepository extends Neo4jRepository<ModelCreation, "RETURN mod, tsr, ts, tpr, tp, tcr, tc, dr, d, mt, ot") Set<ModelCreation> getModelsTreatmentsAndDrugs(@Param("type") String type); + @Query("MATCH (model:ModelCreation)-[ii:IMPLANTED_IN]-(samp:Sample)--(ps:PatientSnapshot)-[tsr:SUMMARY_OF_TREATMENT]-(ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp:TreatmentProtocol)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:TREATMENT]-(d:Treatment) " + + "WHERE model.dataSource = {dataSource} " + + "WITH model, ii, samp, ps, tsr, ts, tpr, tp, tcr, tc, dr, d " + + "OPTIONAL MATCH (tp)-[resp:RESPONSE]-(res:Response) " + + "RETURN model, ii, samp, ps, tsr, ts, tpr, tp, tcr, tc, dr, d,resp, res") + List<ModelCreation> findModelFromPatienSnapshotWithTreatmentSummaryByDataSource(@Param("dataSource")String dataSource); + + @Query("MATCH(model:ModelCreation)-[tsr:SUMMARY_OF_TREATMENT]-(ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp:TreatmentProtocol)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:TREATMENT]-(d:Treatment) " + + "WHERE toLower(model.dataSource) = toLower({dataSource}) " + + "WITH model,tsr, ts, tpr, tp, tcr, tc, dr, d " + + "OPTIONAL MATCH (tp)-[resp:RESPONSE]-(res:Response) " + + "RETURN model,tsr, ts, tpr, tp, tcr, tc, dr, d, res, resp" ) + List<ModelCreation> findModelsWithTreatmentSummaryByDataSource(@Param("dataSource") String dataSource); } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/MolecularCharacterizationRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/MolecularCharacterizationRepository.java index 06dd72e217663f7ab9dc869a119beb73816d9069..9b8a9e66fed4e627cd4dbb4d4a826508addb16c8 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/MolecularCharacterizationRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/MolecularCharacterizationRepository.java @@ -29,16 +29,6 @@ public interface MolecularCharacterizationRepository extends PagingAndSortingRep List<MolecularCharacterization> findPatientPlatformByModelId(@Param("dataSource") String dataSource, @Param("modelId") String modelId); - @Query("MATCH (molch:MolecularCharacterization) " + - "WHERE molch.type = {type} " + - "WITH molch " + - "MATCH (molch)-[awr:ASSOCIATED_WITH]-(mAss:MarkerAssociation) " + - "WHERE exists(mAss.aminoAcidChange) " + - "WITH molch, awr, mAss " + - "MATCH (mAss)-[mr:MARKER]-(m:Marker) " + - "RETURN distinct molch, awr, mAss, mr, m") - Collection<MolecularCharacterization> getAllDistinctByType(@Param("type") String type); - @Query("MATCH (molch:MolecularCharacterization) " + "WHERE molch.type = {type} " + "OPTIONAL MATCH (molch)-[plr:PLATFORM_USED]-(pl:Platform) " + diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/OntologyTermRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/OntologyTermRepository.java index 3f13b26761b717ff8085150ff737f1573b456c2f..b8387e9bd8abcb1fe0e91c1ef009d1e2dd74c0cb 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/OntologyTermRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/OntologyTermRepository.java @@ -8,7 +8,6 @@ import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.List; -import java.util.Set; /** * Created by csaba on 07/06/2017. @@ -40,25 +39,12 @@ public interface OntologyTermRepository extends PagingAndSortingRepository<Ontol @Query("MATCH (ot:OntologyTerm) RETURN ot") Collection<OntologyTerm> findAll(); - @Query("MATCH (st:OntologyTerm)<-[*]-(term:OntologyTerm) " + - "WHERE st.label = {label} " + - "RETURN sum(term.indirectMappedSamplesNumber)") - int getIndirectMappingNumber(@Param("label") String label); - - @Query("MATCH (st:OntologyTerm)<-[*]-(term:OntologyTerm) " + - "WHERE st.label = {label} " + - "RETURN term, st") - Set<OntologyTerm> getDistinctSubTreeNodes(@Param("label") String label); - @Query("MATCH (o:OntologyTerm) RETURN count(o)") int getOntologyTermNumber(); @Query("MATCH (o:OntologyTerm) WHERE o.type = {type} RETURN count(o)") int getOntologyTermNumberByType(@Param("type") String type); - @Query("match (o:OntologyTerm) RETURN o SKIP {from} LIMIT {to}") - Collection<OntologyTerm> findAllFromTo(@Param("from") int from, @Param("to") int to); - @Query("match (o:OntologyTerm) WHERE o.type = {type} RETURN o SKIP {from} LIMIT {to}") Collection<OntologyTerm> findAllByTypeFromTo(@Param("type") String type, @Param("from") int from, @Param("to") int to); @@ -67,7 +53,6 @@ public interface OntologyTermRepository extends PagingAndSortingRepository<Ontol "RETURN parent") Collection<OntologyTerm> findAllDirectParents(@Param("url") String url); - @Query("MATCH (o:OntologyTerm) WHERE o.directMappedSamplesNumber > 0 RETURN o") Collection<OntologyTerm> findAllWithNotZeroDirectMappingNumber(); diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientRepository.java index 87be07334931f61c3619214d657fb500a1fefbf0..c641d8f390bf1840572f95d23da8887b8995b8fe 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientRepository.java @@ -32,22 +32,6 @@ public interface PatientRepository extends Neo4jRepository<Patient, Long> { "RETURN p, patRel, ps, sf, s, ii, mod, o, t, ot, tt, ssr, ss ORDER BY p.externalId") List<Patient> findPatientTumorAtCollectionDataByDS(@Param("g") Group g); - - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + - "MATCH (s:Sample)-[sf:SAMPLED_FROM]-(ps:PatientSnapshot)-[pt:PATIENT]-(p:Patient) " + - "WHERE mod.sourcePdxId = {modelId} " + - "RETURN mod, ii, s, ps, p, sf, pt") - Patient findByModelId(@Param("modelId") String modelId); - - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + - "MATCH (s:Sample)--(ps:PatientSnapshot)--(p:Patient) " + - "WHERE s.sourceSampleId = {sampleId} " + - "RETURN mod, ii, s, ps, p") - Patient findBySampleId(@Param("sampleId") String sampleId); - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + "WHERE mod.sourcePdxId = {modelId} " + "AND toLower(mod.dataSource) = toLower({dataSource}) "+ @@ -58,43 +42,6 @@ public interface PatientRepository extends Neo4jRepository<Patient, Long> { Patient findByDataSourceAndModelId(@Param("dataSource") String dataSource, @Param("modelId") String modelId); - @Query("MATCH(pat:Patient)-[patRel:COLLECTION_EVENT]-(ps:PatientSnapshot)-[sfrm:SAMPLED_FROM]-(psamp:Sample)-[char:CHARACTERIZED_BY]-(molch:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) " + - "WITH pat,patRel,ps,sfrm,psamp,char,molch,mAss,m " + - "Match (psamp)-[imp:IMPLANTED_IN]-(mc:ModelCreation) " + - " WHERE psamp.dataSource = {dataSource} " + - " AND mc.sourcePdxId = {modelId} " + - " AND (mc.technology = {tech} OR {tech} = '' ) " + - - - " OR toLower(m.hgncSymbol) CONTAINS toLower({search})" + - " OR toLower(mc.technology) CONTAINS toLower({search})" + - " OR any( property in keys(mAss) where toLower(mAss[property]) CONTAINS toLower({search}) ) " + - - " RETURN pat,patRel,ps,sfrm,psamp,char,molch,mAss,m SKIP {skip} LIMIT {lim} ") - Set<Patient> findSpecimenBySourcePdxIdAndPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("search") String search, - @Param("skip") int skip, - @Param("lim") int lim); - - - @Query("MATCH(pat:Patient)-[patRel:PATIENT]-(ps:PatientSnapshot)-[sfrm:SAMPLED_FROM]-(psamp:Sample)-[char:CHARACTERIZED_BY]-(molch:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) " + - "WITH pat,patRel,ps,sfrm,psamp,char,molch,mAss,m " + - "Match (psamp)-[imp:IMPLANTED_IN]-(mc:ModelCreation) " + - " WHERE psamp.dataSource = {dataSource} " + - " AND mc.sourcePdxId = {modelId} " + - " AND (mc.technology = {tech} OR {tech} = '' ) " + - - " OR toLower(m.hgncSymbol) CONTAINS toLower({search}) " + - " OR toLower(mc.technology) CONTAINS toLower({search}) " + - " OR any( property in keys(mAss) where toLower(mAss[property]) CONTAINS toLower({search}) ) " + - " RETURN count(*) ") - Integer countByBySourcePdxIdAndPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("search") String search); - @Query("MATCH (p:Patient)--(ps:PatientSnapshot)--(s:Sample)--(mod:ModelCreation) " + "WHERE mod.dataSource = {dataSource} " + "AND mod.sourcePdxId = {modelId} " + @@ -141,6 +88,7 @@ public interface PatientRepository extends Neo4jRepository<Patient, Long> { "AND samp.sourceSampleId = {sourceSampleId} " + " RETURN mod.sourcePdxId ") String getModelIdByDataSourceAndPatientSampleId(@Param("dataSource") String dataSource, - @Param("sourceSampleId") String modelId); + @Param("sourceSampleId") String modelId); } + diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientSnapshotRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientSnapshotRepository.java index 78b836ab64b7023d67e73ea7d3bbe290ec42be93..ec66329335ce13e03dbd6d12f97d920a31fe186b 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientSnapshotRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/PatientSnapshotRepository.java @@ -6,7 +6,6 @@ import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; import java.util.Set; @Repository @@ -15,25 +14,6 @@ public interface PatientSnapshotRepository extends Neo4jRepository<PatientSnapsh @Query("MATCH (ps:PatientSnapshot)--(p:Patient) WHERE p.externalId = {patientId} RETURN ps") Set<PatientSnapshot> findByPatient(@Param("patientId") String patientId); - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample)-[sf:SAMPLED_FROM]-(ps:PatientSnapshot)-[pr:PATIENT]-(p:Patient) \n" + - "WHERE mod.sourcePdxId = {modelId} " + - "WITH mod, ii, s, sf, ps, pr, p " + - "OPTIONAL MATCH (s)-[ot:ORIGIN_TISSUE]-(t1:Tissue) " + - "OPTIONAL MATCH (s)-[ss:SAMPLE_SITE]-(t2:Tissue) " + - - "RETURN mod,ii,s,sf,ps, p, pr, t1, t2, ot, ss") - PatientSnapshot findByModelId(@Param("modelId") String modelId); - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample)-[sf:SAMPLED_FROM]-(ps:PatientSnapshot)-[pr:PATIENT]-(p:Patient) " + - "WHERE mod.sourcePdxId = {modelId} " + - "AND toLower(s.dataSource) = toLower({dataSource}) "+ - "WITH mod, ii, s, sf, ps, pr, p " + - "OPTIONAL MATCH (s)-[ot:ORIGIN_TISSUE]-(t1:Tissue) " + - "OPTIONAL MATCH (s)-[ss:SAMPLE_SITE]-(t2:Tissue) " + - - "RETURN mod,ii,s,sf,ps, p, pr, t1, t2, ot, ss") - List<PatientSnapshot> findByDataSourceAndModelId(@Param("dataSource") String dataSource, @Param("modelId") String modelId); - @Query("MATCH (p:Patient)--(ps:PatientSnapshot) " + "WHERE p.externalId = {patientId} " + "AND p.dataSource = {dataSource} " + diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/PlatformAssociationRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/PlatformAssociationRepository.java index bdd61ec9ec60cda8d0b2263ae484e97983683305..56f1dbe7d498f5cf076c964781d96fb99b970ec4 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/PlatformAssociationRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/PlatformAssociationRepository.java @@ -14,8 +14,6 @@ import java.util.Set; @Repository public interface PlatformAssociationRepository extends PagingAndSortingRepository<PlatformAssociation, Long> { - Set<PlatformAssociation> findAllByPlatform_Name(@Param("name") String name); - @Query("MATCH (pa:PlatformAssociation), (p:Platform), (ds:Group) WHERE (pa)--(p)--(ds) AND ds.name = {name} AND ds.type='Provider' RETURN pa") Set<PlatformAssociation> findByPlatform_ExternalDataSource_Name(@Param("name") String name); diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/QualityAssuranceRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/QualityAssuranceRepository.java index ec294cb3eb635d4d1a40db1cb7fffda8de6bde0c..8cd98ede7c7fa55d844dda3dfe9245a4ecbb3bb5 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/QualityAssuranceRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/QualityAssuranceRepository.java @@ -1,6 +1,7 @@ package org.pdxfinder.graph.repositories; import org.pdxfinder.graph.dao.QualityAssurance; +import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -9,6 +10,7 @@ import org.springframework.stereotype.Repository; @Repository public interface QualityAssuranceRepository extends Neo4jRepository<QualityAssurance, Long> { - QualityAssurance findFirstByTechnologyAndDescription(@Param("technology") String technology, @Param("description") String description); + @Query("MATCH (qa:QualityAssurance) WHERE qa.technology = {technology} AND qa.description = {description} AND qa.passage = {passage} RETURN qa") + QualityAssurance findByTechnologyAndDescriptionAndPassage(@Param("technology") String technology, @Param("description") String description, @Param("passage") String passage); } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/ResponseRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/ResponseRepository.java index 4f931cb64879377dd0efe526e7d2f5e1afc1ddbc..9f8aa697748589a138b44fa46d48c3023cbb5f72 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/ResponseRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/ResponseRepository.java @@ -13,9 +13,6 @@ import java.util.List; @Repository public interface ResponseRepository extends PagingAndSortingRepository<Response, Long>{ - @Query("MATCH (r:Response) RETURN DISTINCT r.description") - List<String> findAllResponses(); - @Query("MATCH (m:ModelCreation)--(ts:TreatmentSummary)--(tp:TreatmentProtocol)--(r:Response) RETURN DISTINCT r.description") List<String> findAllSpecimenDrugResponses(); diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/SampleRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/SampleRepository.java index f6cb8bfb31f980cb62013c0f96b44e3d5ee0a033..c1163101e9e8c1f12f4c0ea5c5a9b3f869baf411 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/SampleRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/SampleRepository.java @@ -1,16 +1,11 @@ package org.pdxfinder.graph.repositories; - -import org.pdxfinder.graph.dao.ModelCreation; import org.pdxfinder.graph.dao.Sample; import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; - import java.util.Collection; -import java.util.List; -import java.util.Set; /** * Repository for managing creating, finding, and deleting sample objects @@ -21,71 +16,9 @@ public interface SampleRepository extends PagingAndSortingRepository<Sample, Lon @Query("MATCH (s:Sample) WHERE s.sourceSampleId = {sourceSampleId} AND s.dataSource = {dataSource} return s") Sample findBySourceSampleIdAndDataSource(@Param("sourceSampleId") String sourceSampleId, @Param("dataSource") String dataSource) ; - Set<Sample> findByDataSource(String dataSource); - - @Query("MATCH (s:Sample)-[o:ORIGIN_TISSUE]-(t:Tissue) where s.diagnosis contains {diag} return s,o,t order by s.diagnosis limit 30") - Collection<Sample> findByDiagnosisContains(@Param("diag") String diag); - - @Query("MATCH (s:Sample)-[o:ORIGIN_TISSUE]-(t:Tissue) " + - "MATCH (s:Sample)--(:MolecularCharacterization)--(:MarkerAssociation)--(m:Marker) " + - "WHERE toLower(s.diagnosis) CONTAINS toLower({diag}) " + - "AND m.name IN {markers} return s,o,t") - Collection<Sample> findByDiagnosisContainsAndHaveMarkers(@Param("diag") String diag, @Param("markers") String[] markers); - - - @Query("MATCH (s:Sample)-[o:ORIGIN_TISSUE]-(t:Tissue) " + - "MATCH (s:Sample)-[cb:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[aw:ASSOCIATED_WITH]-(ma:MarkerAssociation)-[mar:MARKER]-(m:Marker) " + - "MATCH (s:Sample)-[ot:OF_TYPE]-(tt:TumorType) " + - "MATCH (s:Sample)-[ii:IMPLANTED_IN]-(mod:ModelCreation) "+ - "WHERE (toLower(s.diagnosis) CONTAINS toLower({diag}) OR {diag}='') " + - "AND (m.name IN {markers} OR {markers}=[]) " + - "AND (s.dataSource IN {dataSource} OR {dataSource}=[]) " + - "AND (tt.name IN {tumorType} OR {tumorType}=[]) " + - "RETURN s,o,t,ot, tt, mc, ma, m, mar, cb, aw, ii, mod") - Collection<Sample> findByMultipleFilters(@Param("diag") String diag, @Param("markers") String[] markers, - @Param("dataSource") String[] dataSource, @Param("tumorType") String[] tumorType); - - - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + - "WHERE mod.sourcePdxId = {sourcePdxId} " + - "WITH s, mod, ii " + - "OPTIONAL MATCH (s)-[o:ORIGIN_TISSUE]-(t:Tissue) " + - "OPTIONAL MATCH (s)-[cb:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[aw:ASSOCIATED_WITH]-(ma:MarkerAssociation)-[mar:MARKER]-(m:Marker) " + - "OPTIONAL MATCH (s)-[ot:OF_TYPE]-(tt:TumorType) " + - "RETURN mod,ii,s,o,t,ot, tt, mc, ma, m, mar, cb, aw") - Sample findBySourcePdxId(@Param("sourcePdxId") String sourcePdxId); - - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + - "WHERE mod.sourcePdxId = {sourcePdxId} " + - "AND toLower(s.dataSource) = toLower({dataSource}) " + - "WITH s, mod, ii " + - "OPTIONAL MATCH (s)-[o:ORIGIN_TISSUE]-(t:Tissue) " + - "OPTIONAL MATCH (s)-[ssr:SAMPLE_SITE]-(ss:Tissue) " + - - "OPTIONAL MATCH (s)-[cb:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[aw:ASSOCIATED_WITH]-(ma:MarkerAssociation)-[mar:MARKER]-(m:Marker) " + - "OPTIONAL MATCH (s)-[ot:OF_TYPE]-(tt:TumorType) " + - "OPTIONAL MATCH (s)-[mapped:MAPPED_TO]-(oterm:OntologyTerm) " + - "RETURN mod,ii,s,o,t,ot, tt, mc, ma, m, mar, cb, aw, mapped, oterm, ssr, ss") - Sample findByDataSourceAndPdxId(@Param("dataSource") String dataSource, @Param("sourcePdxId") String sourcePdxId); - - - @Query("MATCH (p:Patient--(ps:PatientSnapshot)--(s:Sample) " + - "WHERE p.externalId = {patientId} " + - "AND p.dataSource = {dataSource} " + - "AND s.sourceSampleId = {sampleId} " + - "RETURN s") - Sample findHumanSampleByPatientIdAndDataSourceAndSampleId(@Param("patientId") String patientId, - @Param("dataSource") String dataSource, - @Param("sampleId") String sampleId); - @Query("MATCH (ps:PatientSnapshot)--(s:Sample) WHERE s.dataSource = {dataSource} AND s.sourceSampleId = {sampleId} RETURN s") Sample findHumanSampleBySampleIdAndDataSource(@Param("sampleId") String sampleId, @Param("dataSource") String dataSource); - @Query("MATCH (sp:Specimen)--(s:Sample) WHERE s.sourceSampleId = {sampleId} AND s.dataSource = {dataSource} RETURN s") - Sample findMouseSampleBySampleIdAndDataSource(@Param("sampleId") String sampleId, @Param("dataSource") String dataSource); - @Query("MATCH (ps:PatientSnapshot)--(s:Sample) RETURN count(s)") int findHumanSamplesNumber(); @@ -96,45 +29,9 @@ public interface SampleRepository extends PagingAndSortingRepository<Sample, Lon "RETURN s, ot,t, oft, tt SKIP {from} LIMIT {to}") Collection<Sample> findHumanSamplesFromTo(@Param("from") int from, @Param("to") int to); - @Query("MATCH (ps:PatientSnapshot)-[sf:SAMPLED_FROM]-(s:Sample) WHERE NOT (s)-[:MAPPED_TO]-() " + - "WITH s " + - "OPTIONAL MATCH (s)-[ot:ORIGIN_TISSUE]-(ti:Tissue) " + - "OPTIONAL MATCH (s)-[oft:OF_TYPE]-(t:TumorType) " + - "RETURN DISTINCT s, ti, t, ot, oft ORDER BY s.diagnosis") - Collection<Sample> findSamplesWithoutOntologyMapping(); - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) WHERE mod.sourcePdxId = {modelId} AND mod.dataSource = {ds} RETURN s") Sample findHumanSampleByModelIdAndDS(@Param("modelId") String modelId, @Param("ds") String ds); - @Query("MATCH (mod:ModelCreation)--(sp:Specimen)--(s:Sample)" + - "WHERE mod.sourcePdxId = {modelId} " + - "AND mod.dataSource = {ds} " + - "AND sp.externalId = {specimenId} " + - "RETURN s") - Sample findMouseSampleByModelIdAndDataSourceAndSpecimenId(@Param("modelId") String modelId, @Param("ds") String dataSource, @Param("specimenId") String specimenId); - - - @Query("MATCH (ps:PatientSnapshot)-[sf:SAMPLED_FROM]-(s:Sample) " + - "WHERE NOT (s)-[:MAPPED_TO]-() " + - "AND s.dataSource = {ds}" + - "WITH s " + - "OPTIONAL MATCH (s)-[ot:ORIGIN_TISSUE]-(ti:Tissue) " + - "OPTIONAL MATCH (s)-[oft:OF_TYPE]-(t:TumorType) " + - "RETURN DISTINCT s, ti, t, ot, oft ORDER BY s.diagnosis") - Collection<Sample> findSamplesWithoutOntologyMappingByDataSource(@Param("ds") String dataSource); - - - @Query("MATCH (mod:ModelCreation)--(sp:Specimen)--(s:Sample) " + - "WHERE mod.sourcePdxId = {modelId} " + - "AND mod.dataSource = {ds} " + - "AND s.sourceSampleId = {sampleId} " + - "WITH s " + - "OPTIONAL MATCH (s)-[cb:CHARACTERIZED_BY]-(mc:MolecularCharacterization) " + - "RETURN s, cb, mc" - ) - Sample findMouseSampleWithMolcharByModelIdAndDataSourceAndSampleId(@Param("modelId") String modelId, @Param("ds") String ds, @Param("sampleId") String sampleId); - @Query("MATCH (mod:ModelCreation)--(s:Sample)--(ps:PatientSnapshot) " + "WHERE mod.sourcePdxId = {modelId} " + @@ -146,17 +43,7 @@ public interface SampleRepository extends PagingAndSortingRepository<Sample, Lon Sample findHumanSampleWithMolcharByModelIdAndDataSource(@Param("modelId") String modelId, @Param("ds") String ds); - @Query("MATCH (mod:ModelCreation)--(sp:Specimen)--(hs:HostStrain) " + - "WHERE mod.sourcePdxId = {modelId} " + - "AND mod.dataSource = {ds} " + - "AND hs.symbol = {nomenclature} " + - "AND sp.passage = {passage}" + - "WITH sp " + - "MATCH (sp)--(s:Sample) " + - "RETURN s") - Sample findMouseSampleByModelIdAndDataSourceAndPassageAndNomenclature(@Param("modelId") String modelId, @Param("ds") String dataSource, @Param("passage") String passage, @Param("nomenclature") String nomenclature); - -@Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + + @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(s:Sample) " + "WHERE mod.sourcePdxId = {sourcePdxId} " + "AND toLower(mod.dataSource) = toLower({dataSource}) " + "WITH s " + @@ -173,17 +60,4 @@ public interface SampleRepository extends PagingAndSortingRepository<Sample, Lon "RETURN s") Sample findSampleByMolcharId(@Param("id") Long id); - - @Query("MATCH (mod:ModelCreation)-[ii:IMPLANTED_IN]-(samp:Sample) " + - "-[char:CHARACTERIZED_BY]-(molchar:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) WHERE molchar.type={molcharType} " + - " WITH mod, ii, samp, char,molchar, assoc,mAss, aw,m " + - " MATCH (molchar)-[pl:PLATFORM_USED]-(tech:Platform) " + - " WHERE mod.dataSource = {dataSource} " + - " AND mod.sourcePdxId = {modelId} " + - - " RETURN ii, samp, char,molchar, assoc,mAss, aw,m,pl,tech ") - Sample findHumanSampleBySourcePdxIdAndMolcharType(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("molcharType") String molcharType); - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/SpecimenRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/SpecimenRepository.java index 0c53c3fe80a8e77f8aeccdc3041c9476d1444b92..34763b4bc9692541050146ffe44f34a1d0ffa4ed 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/SpecimenRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/SpecimenRepository.java @@ -40,43 +40,6 @@ public interface SpecimenRepository extends Neo4jRepository<Specimen, Long> { @Param("specimenId") String specimenId, @Param("passage") String passage); - @Query("MATCH (mod:ModelCreation)--(spec:Specimen) " + - "WHERE mod.dataSource = {dataSource} " + - "AND mod.sourcePdxId = {modelId} " + - "AND spec.passage = {passage} " + - "RETURN spec") - List<Specimen> findByModelIdAndDataSourceAndAndPassage( - @Param("modelId") String modelId, - @Param("dataSource") String dataSource, - @Param("passage") String passage); - - - @Query("MATCH (mod:ModelCreation)-[sp:SPECIMENS]-(spec:Specimen)-[sfrm:SAMPLED_FROM]-(msamp:Sample)" + - "-[char:CHARACTERIZED_BY]-(molchar:MolecularCharacterization)-[assoc:ASSOCIATED_WITH]->(mAss:MarkerAssociation)-[aw:MARKER]-(m:Marker) WHERE molchar.type={molcharType} " + - " WITH mod, sp, spec, sfrm,msamp, char,molchar, assoc,mAss, aw,m " + - " MATCH (molchar)-[pl:PLATFORM_USED]-(tech:Platform) " + - - " WHERE mod.dataSource = {dataSource} " + - " AND mod.sourcePdxId = {modelId} " + - - " RETURN spec, sp, sfrm,msamp, char,molchar, assoc,mAss, aw,m,pl,tech ") - List<Specimen> findSpecimenBySourcePdxId(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("molcharType") String molcharType); - - - - @Query("MATCH (mod:ModelCreation)-[spr:SPECIMENS]-(sp:Specimen) " + - "WHERE mod.dataSource = {dataSource} " + - "AND mod.sourcePdxId = {modelId} " + - "WITH sp " + - "OPTIONAL MATCH (sp)-[etr:ENGRAFTMENT_TYPE]-(et:EngraftmentType) " + - "OPTIONAL MATCH (sp)-[esr:ENGRAFTMENT_SITE]-(es:EngraftmentSite) " + - "OPTIONAL MATCH (sp)-[emr:ENGRAFTMENT_MATERIAL]-(em:EngraftmentMaterial) " + - "OPTIONAL MATCH (sp)-[hsr:HOST_STRAIN]-(hs:HostStrain) " + - "RETURN sp, etr, et, esr, es, emr, em, hsr, hs") - List<Specimen> findByDataSourceAndModelId(@Param("dataSource") String dataSource, - @Param("modelId") String modelId); @Query("MATCH (mod:ModelCreation)-[sp:SPECIMENS]-(spec:Specimen)-[sfrm:SAMPLED_FROM]-(msamp:Sample) " + " -[char:CHARACTERIZED_BY]-(molchar:MolecularCharacterization) " + @@ -92,52 +55,6 @@ public interface SpecimenRepository extends Neo4jRepository<Specimen, Long> { @Param("modelId") String modelId, @Param("tech") String tech); - - - @Query("MATCH (mod:ModelCreation)--(spec:Specimen)--(msamp:Sample)--(molchar:MolecularCharacterization)-->(mAss:MarkerAssociation)--(m:Marker) " + - " WITH mod,spec,msamp,molchar,mAss,m " + - " MATCH (molchar)--(tech:Platform) " + - - " WHERE mod.dataSource = {dataSource} " + - " AND mod.sourcePdxId = {modelId} " + - " AND (tech.name = {tech} OR {tech} = '' ) " + - " AND (spec.passage = {passage} OR {passage} = '' )" + - - " AND ( toLower(spec.externalId) CONTAINS toLower({search})" + - " OR toLower(m.hgncSymbol) CONTAINS toLower({search})" + - " OR toLower(tech.name) CONTAINS toLower({search})" + - " OR any( property in keys(mAss) where toLower(mAss[property]) CONTAINS toLower({search}) ) ) " + - " RETURN count(*) ") - Integer countBySearchParameterAndPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("passage") String passage, - @Param("search") String search); - - - - @Query("MATCH (mod:ModelCreation)--(spec:Specimen)--(msamp:Sample)--(molchar:MolecularCharacterization)-->(mAss:MarkerAssociation)--(m:Marker) " + - " WITH mod,spec,msamp,molchar,mAss,m " + - " MATCH (molchar)--(tech:Platform) " + - - " WHERE mod.dataSource = {dataSource} " + - " AND mod.sourcePdxId = {modelId} " + - " AND (tech.name = {tech} OR {tech} = '' ) " + - " AND (spec.passage = {passage} OR {passage} = '' )" + - - " RETURN count(*) ") - Integer countByPlatform(@Param("dataSource") String dataSource, - @Param("modelId") String modelId, - @Param("tech") String tech, - @Param("passage") String passage); - - - @Query("MATCH (mod:ModelCreation)--(sp:Specimen) WHERE mod.sourcePdxId = {modelId} AND mod.dataSource = {dataSource} RETURN sp") - List<Specimen> findByModelIdAndDataSource(@Param("modelId") String modelId, @Param("dataSource") String dataSource); - - - - @Query("MATCH (mod:ModelCreation)--(sp:Specimen)--(hs:HostStrain) " + "WHERE id(mod) = {model} " + "AND sp.passage = {passage} " + @@ -147,7 +64,6 @@ public interface SpecimenRepository extends Neo4jRepository<Specimen, Long> { "RETURN sp, sfr, s, cbr, mc, pur, pl") Specimen findByModelAndPassageAndNomenClature(@Param("model") ModelCreation modelCreation, @Param("passage") String passage, @Param("symbol") String nomenclature); - @Query("MATCH (sp:Specimen)--(s:Sample)--(mc:MolecularCharacterization) " + "WHERE id(mc) = {mc} " + "RETURN sp") @@ -159,8 +75,4 @@ public interface SpecimenRepository extends Neo4jRepository<Specimen, Long> { "OPTIONAL MATCH (sp)-[sfr:SAMPLED_FROM]-(s:Sample)-[cbr:CHARACTERIZED_BY]-(mc:MolecularCharacterization)-[pur:PLATFORM_USED]-(pl:Platform) " + "RETURN sp, sfr, s, cbr, mc, pur, pl") List<Specimen> findAllWithMolcharDataByModel(@Param("model") ModelCreation model); - - - - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentProtocolRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentProtocolRepository.java index 904dcb88bec6c949daf6efdc77a2907b9c73e30f..b8165dc4741b8dfbec2ba6b68a59c3071df95016 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentProtocolRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentProtocolRepository.java @@ -1,11 +1,9 @@ package org.pdxfinder.graph.repositories; import org.pdxfinder.graph.dao.TreatmentProtocol; -import org.springframework.data.neo4j.annotation.Query; import org.springframework.data.neo4j.repository.Neo4jRepository; import org.springframework.stereotype.Repository; -import java.util.List; /* * Created by csaba on 23/10/2017. @@ -14,11 +12,4 @@ import java.util.List; public interface TreatmentProtocolRepository extends Neo4jRepository<TreatmentProtocol, Long> { - - @Query("MATCH (tp:TreatmentProtocol) RETURN DISTINCT tp.drug") - List<List<String>> findDrugNames(); - - - - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentRepository.java index bd6ccc1465abe7bace422cf2ace0ac3e484fd705..a8c116bb16bb158427508b58be7ab5af00abb703 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentRepository.java @@ -23,15 +23,6 @@ public interface TreatmentRepository extends Neo4jRepository<Treatment, Long> { int findPatientTreatmentNumberByDS(@Param("ds") String ds); - @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary) RETURN count(ts) ") - int findModelTreatmentNumber(); - - @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary) " + - "WHERE mod.dataSource = {ds} "+ - "RETURN count(ts) ") - int findModelTreatmentNumberByDS(@Param("ds") String ds); - - @Query("MATCH (ps:PatientSnapshot)--(ts:TreatmentSummary)" + "WITH ts SKIP {from} LIMIT {batch}"+ "MATCH (ts)-[tpr:TREATMENT_PROTOCOL]-(tp:TreatmentProtocol)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)--(tr:Treatment) "+ @@ -63,6 +54,4 @@ public interface TreatmentRepository extends Neo4jRepository<Treatment, Long> { "return COLLECT(distinct gr.abbreviation+ '___' + toLower(t.name)) as abbrAndTreatmentName") TreatmentMappingData getUnmappedPatientTreatments(); - - } diff --git a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentSummaryRepository.java b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentSummaryRepository.java index 700de6d1876b4366905b3af816203f1d1560d378..7faf61058acf0d841ff715eeaa378aa35f169e90 100644 --- a/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentSummaryRepository.java +++ b/data-model/src/main/java/org/pdxfinder/graph/repositories/TreatmentSummaryRepository.java @@ -39,11 +39,6 @@ public interface TreatmentSummaryRepository extends Neo4jRepository<TreatmentSum @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary) WHERE toLower(mod.dataSource) = toLower({dataSource}) AND EXISTS(ts.url) RETURN ts.url LIMIT 1") String findPlatformUrlByDataSource(@Param("dataSource") String dataSource); - @Query("MATCH (ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp:TreatmentProtocol)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:TREATMENT]-(d:Treatment) " + - "MATCH (tp)-[rr:RESPONSE]-(r:Response) " + - "RETURN ts, tpr, tp, tcr, tc, dr, d, rr, r") - List<TreatmentSummary> findAllWithDrugData(); - @Query("MATCH (mod:ModelCreation)--(ts:TreatmentSummary)-[tpr:TREATMENT_PROTOCOL]-(tp:TreatmentProtocol)-[tcr:TREATMENT_COMPONENT]-(tc:TreatmentComponent)-[dr:TREATMENT]-(d:Treatment)-[mtr:MAPPED_TO]-(ot:OntologyTerm) " + "MATCH (tp)-[rr:RESPONSE]-(r:Response) " + "OPTIONAL MATCH (ot)-[sor:SUBCLASS_OF]-(ot2:OntologyTerm) " + diff --git a/data-model/src/main/java/org/pdxfinder/rdbms/dao/MappingEntity.java b/data-model/src/main/java/org/pdxfinder/rdbms/dao/MappingEntity.java index a200150b972787ae570e265b7e3d1d2ba1c4b30d..329d199e6a1d88eb76dbbbbea6bb4818355b0474 100644 --- a/data-model/src/main/java/org/pdxfinder/rdbms/dao/MappingEntity.java +++ b/data-model/src/main/java/org/pdxfinder/rdbms/dao/MappingEntity.java @@ -109,7 +109,7 @@ public class MappingEntity { * The unique String that identifies a Mapping */ @JsonIgnore - @Column(unique = true, nullable = false, columnDefinition="Text") + @Column(nullable = false, columnDefinition="Text") private String mappingKey; diff --git a/data-model/src/main/java/org/pdxfinder/rdbms/repositories/MappingEntityRepository.java b/data-model/src/main/java/org/pdxfinder/rdbms/repositories/MappingEntityRepository.java index eb3bcba371613120628018eeafcf8d203cd54987..1809dd6f93e8e3f1cecd8ae9966434e7200ef845 100644 --- a/data-model/src/main/java/org/pdxfinder/rdbms/repositories/MappingEntityRepository.java +++ b/data-model/src/main/java/org/pdxfinder/rdbms/repositories/MappingEntityRepository.java @@ -9,7 +9,6 @@ import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; -import java.util.Map; import java.util.Optional; @@ -46,19 +45,15 @@ public interface MappingEntityRepository extends JpaRepository<MappingEntity, Lo Pageable pageable); - @Query(value = "select me from MappingEntity me JOIN me.mappingValues mv WHERE KEY(mv) = :dataKey AND mv = :dataValue ") List<MappingEntity> findByAttributeAndValue(@Param("dataKey") String dataKey, @Param("dataValue") String dataValue); - List<MappingEntity> findByEntityTypeAndMapTypeIsNotNull(String entityType); List<MappingEntity> findByEntityTypeAndStatusIsNot(String entityType, String statusIsNot); - - - + boolean existsByEntityId(Long entityId); @Query("SELECT distinct lower(mv), " + " count(case when me.status = 'unmapped' THEN 1 END) as unmapped, " + diff --git a/data-model/src/test/java/org/pdxfinder/BaseTestWithPersistence.java b/data-model/src/test/java/org/pdxfinder/BaseTestWithPersistence.java deleted file mode 100644 index 21c2647449522a8e9c50d72cbe9b1c35f8021992..0000000000000000000000000000000000000000 --- a/data-model/src/test/java/org/pdxfinder/BaseTestWithPersistence.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.pdxfinder; - -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.transaction.annotation.Transactional; - -@RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) -@ContextConfiguration(classes = {TestConfigWithPersistence.class}) -@TestPropertySource(locations = {"classpath:ogm.properties"}) -@Transactional -@Ignore -public class BaseTestWithPersistence { - -} diff --git a/data-model/src/test/java/org/pdxfinder/TestConfig.java b/data-model/src/test/java/org/pdxfinder/TestConfig.java index 47c6166c99277adb1e196562256a257a20499828..f07a6fc8a44b8437d1fc0fd10bab992c386edde3 100644 --- a/data-model/src/test/java/org/pdxfinder/TestConfig.java +++ b/data-model/src/test/java/org/pdxfinder/TestConfig.java @@ -19,7 +19,7 @@ public class TestConfig{ @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { - return new org.neo4j.ogm.config.Configuration(); + return new org.neo4j.ogm.config.Configuration.Builder().build(); } @Bean diff --git a/data-model/src/test/java/org/pdxfinder/TestConfigWithPersistence.java b/data-model/src/test/java/org/pdxfinder/TestConfigWithPersistence.java deleted file mode 100644 index ba46bc22a7ef35253ef93ecc9ae6898744efc5b8..0000000000000000000000000000000000000000 --- a/data-model/src/test/java/org/pdxfinder/TestConfigWithPersistence.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.pdxfinder; - -import org.neo4j.ogm.session.SessionFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; -import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import java.nio.file.Paths; - -@Configuration -@EnableTransactionManagement -@ComponentScan(value = "org.pdxfinder") -@EnableNeo4jRepositories("org.pdxfinder.graph.repositories") -public class TestConfigWithPersistence { - - @Bean - public org.neo4j.ogm.config.Configuration getConfiguration() { - org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); - - String pathToDb = Paths.get(".").toAbsolutePath().normalize().toString() + "/target/test_graph.db"; - config - .driverConfiguration() - .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver") - .setURI("file://" + pathToDb); - - System.out.println(config); - - return config; - } - - @Bean - public SessionFactory sessionFactory() { - return new SessionFactory(getConfiguration(), "org.pdxfinder"); - } - - @Bean - public Neo4jTransactionManager transactionManager() { - return new Neo4jTransactionManager(sessionFactory()); - } - -} - - diff --git a/data-model/src/test/java/org/pdxfinder/graph/dao/DataProjectionsTimeTest.java b/data-model/src/test/java/org/pdxfinder/graph/dao/DataProjectionsTimeTest.java index 2f19158e8340c219aeee727e56cd4e8ec5dd5d6b..33187f84346b4f7a622ab4b1ef392d25ae588bdb 100644 --- a/data-model/src/test/java/org/pdxfinder/graph/dao/DataProjectionsTimeTest.java +++ b/data-model/src/test/java/org/pdxfinder/graph/dao/DataProjectionsTimeTest.java @@ -3,7 +3,7 @@ package org.pdxfinder.graph.dao; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import org.pdxfinder.BaseTestWithPersistence; +import org.pdxfinder.BaseTest; import org.pdxfinder.graph.repositories.DataProjectionRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -12,7 +12,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -public class DataProjectionsTimeTest extends BaseTestWithPersistence { +public class DataProjectionsTimeTest extends BaseTest { private static final String LABEL = "TEST"; diff --git a/data-model/src/test/java/org/pdxfinder/graph/dao/MarkerAssociationTest.java b/data-model/src/test/java/org/pdxfinder/graph/dao/MarkerAssociationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d4c6abda3979074a8facd644e2ae9604aef1f60b --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/dao/MarkerAssociationTest.java @@ -0,0 +1,27 @@ +package org.pdxfinder.graph.dao; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collections; + +public class MarkerAssociationTest { + + + + @Test + public void Given_MarkerAssociation_When_EncodeIsCalled_Then_DataInRightFormat(){ + + MarkerAssociation ma = new MarkerAssociation(); + MolecularData md = new MolecularData(); + md.setMarker("KRAS"); + + ma.setMolecularDataList(Collections.singletonList(md)); + + ma.encodeMolecularData(); + + Assert.assertEquals(1, ma.getDataPoints()); + + } + +} diff --git a/data-model/src/test/java/org/pdxfinder/graph/dao/PatientSnapshotTest.java b/data-model/src/test/java/org/pdxfinder/graph/dao/PatientSnapshotTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c052a6ae189141b829ce420f3b95159565f9b89b --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/dao/PatientSnapshotTest.java @@ -0,0 +1,48 @@ +package org.pdxfinder.graph.dao; + + +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashSet; + + +public class PatientSnapshotTest { + + @Test + public void given_PatientSnapshot_when_PaediatricAge_then_AgeBinCorrect(){ + Patient patient = new Patient("test1", new Group()); + + PatientSnapshot patientSnapshot1 = new PatientSnapshot(patient, "1", new HashSet<>(), new TreatmentSummary()); + PatientSnapshot patientSnapshot2 = new PatientSnapshot(patient, "12mo", new HashSet<>()); + patientSnapshot2.addSample(new Sample("sample123")); + PatientSnapshot patientSnapshot3 = new PatientSnapshot(patient, "26mo", "", "", ""); + PatientSnapshot patientSnapshot4 = new PatientSnapshot(patient, "5", "", "", ""); + PatientSnapshot patientSnapshot5 = new PatientSnapshot(patient, "15", "", "", ""); + PatientSnapshot patientSnapshot6 = new PatientSnapshot(patient, "25", "", "", ""); + PatientSnapshot patientSnapshot7 = new PatientSnapshot(patient, "35", "", "", ""); + PatientSnapshot patientSnapshot8 = new PatientSnapshot(patient, "45", "", "", ""); + PatientSnapshot patientSnapshot9 = new PatientSnapshot(patient, "55", "", "", ""); + PatientSnapshot patientSnapshot10 = new PatientSnapshot(patient, "65", "", "", ""); + PatientSnapshot patientSnapshot11 = new PatientSnapshot(patient, "75", "", "", ""); + PatientSnapshot patientSnapshot12 = new PatientSnapshot(patient, "85", "", "", ""); + PatientSnapshot patientSnapshot13 = new PatientSnapshot(patient, "95", "", "", ""); + + + Assert.assertEquals(patientSnapshot1.getAgeBin(), "0-23 months"); + Assert.assertEquals(patientSnapshot2.getAgeBin(), "0-23 months"); + Assert.assertEquals(patientSnapshot3.getAgeBin(), "2-9"); + Assert.assertEquals(patientSnapshot4.getAgeBin(), "2-9"); + Assert.assertEquals(patientSnapshot5.getAgeBin(), "10-19"); + Assert.assertEquals(patientSnapshot6.getAgeBin(), "20-29"); + Assert.assertEquals(patientSnapshot7.getAgeBin(), "30-39"); + Assert.assertEquals(patientSnapshot8.getAgeBin(), "40-49"); + Assert.assertEquals(patientSnapshot9.getAgeBin(), "50-59"); + Assert.assertEquals(patientSnapshot10.getAgeBin(), "60-69"); + Assert.assertEquals(patientSnapshot11.getAgeBin(), "70-79"); + Assert.assertEquals(patientSnapshot12.getAgeBin(), "80-89"); + Assert.assertEquals(patientSnapshot13.getAgeBin(), "90+"); + Assert.assertEquals(false, patientSnapshot2.equals(patientSnapshot3)); + } + +} diff --git a/data-model/src/test/java/org/pdxfinder/graph/repositories/AllLookupNodeRepositoriesTest.java b/data-model/src/test/java/org/pdxfinder/graph/repositories/AllLookupNodeRepositoriesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..86aeea9bc607ff4c2bd8622cb7f6d33c16b09000 --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/repositories/AllLookupNodeRepositoriesTest.java @@ -0,0 +1,138 @@ +package org.pdxfinder.graph.repositories; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.transaction.BeforeTransaction; + +import java.util.Arrays; +import java.util.List; + +/** + * Tests for the Sample Type repository + */ +public class AllLookupNodeRepositoriesTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(AllLookupNodeRepositoriesTest.class); + + private static final String TISSUE_NAME = "TEST_TISSUE"; + private static final String BACKGROUND_STRAIN = "TEST_BACKGROUND_STRAIN"; + private static final String IMPLANTATION_TYPE = "TEST_IMPLANTATION_TYPE"; + private static final String IMPLANTATION_SITE = "TEST_IMPLANTATION_SITE"; + + @Autowired + private + TumorTypeRepository tumorTypeRepository; + + @Autowired + private TissueRepository tissueRepository; + + @Autowired + private HostStrainRepository hostStrainRepository; + + @Autowired + private EngraftmentSiteRepository engraftmentSiteRepository; + + @Autowired + private EngraftmentTypeRepository engraftmentTypeRepository; + + + @Before + public void setupDb() { + } + + @Rollback(false) + @BeforeTransaction + public void cleanDb() { + tumorTypeRepository.deleteAll(); + tissueRepository.deleteAll(); + } + + + @Test + public void createTumorTypes() throws Exception { + + List<String> types = Arrays.asList("Metastasis", "Metastatic", "Not Specified", "Primary Malignancy", "Recurrent/Relapse"); + + for (String type : types) { + TumorType foundType = tumorTypeRepository.findByName(type); + if (foundType == null) { + log.debug("Sample type {} not found. Creating", type); + foundType = new TumorType(type); + tumorTypeRepository.save(foundType); + } + + foundType = tumorTypeRepository.findByName(type); + log.info(" Found Sample type {}", foundType.getName()); + + assert (foundType.getName().equals(type)); + + } + + } + + @Test + public void createTissue() { + + Tissue tissue = tissueRepository.findByName(TISSUE_NAME); + if (tissue == null) { + log.debug("Tissue {} not found. Creating", TISSUE_NAME); + tissue = new Tissue(TISSUE_NAME); + tissueRepository.save(tissue); + } + + Assert.assertNotNull(tissueRepository.findByName(TISSUE_NAME)); + log.info(" Found Tissue {}", tissueRepository.findByName(TISSUE_NAME).getName()); + + } + + @Test + public void createBackgroundStrain() { + + HostStrain bgStrain = hostStrainRepository.findBySymbol(BACKGROUND_STRAIN); + if (bgStrain == null) { + log.debug("Background strain {} not found. Creating", BACKGROUND_STRAIN); + bgStrain = new HostStrain(BACKGROUND_STRAIN); + hostStrainRepository.save(bgStrain); + } + + Assert.assertNotNull(hostStrainRepository.findBySymbol(BACKGROUND_STRAIN)); + log.info(" Found Background Strain {}", hostStrainRepository.findBySymbol(BACKGROUND_STRAIN).getSymbol()); + } + + @Test + public void createImplantationSite() { + + EngraftmentSite site = engraftmentSiteRepository.findByName(IMPLANTATION_SITE); + if (site == null) { + log.debug("Implantation site {} not found. Creating", IMPLANTATION_SITE); + site = new EngraftmentSite(IMPLANTATION_SITE); + engraftmentSiteRepository.save(site); + } + + Assert.assertNotNull(engraftmentSiteRepository.findByName(IMPLANTATION_SITE)); + log.info(" Found Implantation Site {}", engraftmentSiteRepository.findByName(IMPLANTATION_SITE).getName()); + } + + @Test + public void createImplantationType() { + + EngraftmentType type = engraftmentTypeRepository.findByName(IMPLANTATION_TYPE); + if (type == null) { + log.debug("Implantation type {} not found. Creating", IMPLANTATION_TYPE); + type = new EngraftmentType(IMPLANTATION_TYPE); + engraftmentTypeRepository.save(type); + } + + Assert.assertNotNull(engraftmentTypeRepository.findByName(IMPLANTATION_TYPE)); + log.info(" Found Implantation Type {}", engraftmentTypeRepository.findByName(IMPLANTATION_TYPE).getName()); + + } + +} \ No newline at end of file diff --git a/data-model/src/test/java/org/pdxfinder/graph/repositories/PatientRepositoryTest.java b/data-model/src/test/java/org/pdxfinder/graph/repositories/PatientRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c4666365af72caadb48bd6eab1671fc94aeb5eef --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/repositories/PatientRepositoryTest.java @@ -0,0 +1,68 @@ +package org.pdxfinder.graph.repositories; + +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.Group; +import org.pdxfinder.graph.dao.Patient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.sql.Date; +import java.time.Instant; + +/** + * Tests for the Patient data repository + */ + +public class PatientRepositoryTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(PatientRepositoryTest.class); + private String extDsName = "TEST_SOURCE"; + private String extDsAbbrev = "TS"; + + @Autowired + private GroupRepository groupRepository; + + @Autowired + private PatientRepository patientRepository; + + @Before + public void setupDb() { + + patientRepository.deleteAll(); + groupRepository.deleteAll(); + + Group ds = groupRepository.findByNameAndType(extDsName, "Provider"); + if(ds == null){ + log.info("Group not found. Creating", extDsName); + + ds = new Group(extDsName, extDsAbbrev, "Provider"); + groupRepository.save(ds); + + } + } + + @Test + public void persistedPatientShouldBeRetrievableFromGraphDb() throws Exception { + + Group group = groupRepository.findByNameAndType(extDsName, "Provider"); + + Patient femalePatient = new Patient("-9999", "F", null, null, group); + patientRepository.save(femalePatient); + + Patient foundFemalePatient = patientRepository.findBySex("F").iterator().next(); + assert (foundFemalePatient != null); + assert (foundFemalePatient.getSex().equals("F")); + + log.info(foundFemalePatient.toString()); + + patientRepository.delete(patientRepository.findByExternalIdAndGroup("-9999", group)); + Patient notFoundFemalePatient = patientRepository.findByExternalIdAndGroup("-9999", group); + assert (notFoundFemalePatient == null); + + + } + +} \ No newline at end of file diff --git a/data-model/src/test/java/org/pdxfinder/graph/repositories/PlatformRepositoryTest.java b/data-model/src/test/java/org/pdxfinder/graph/repositories/PlatformRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..804070571e46066dd3a19a8d298afcf4612776a0 --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/repositories/PlatformRepositoryTest.java @@ -0,0 +1,85 @@ +package org.pdxfinder.graph.repositories; + +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.sql.Date; +import java.time.Instant; +import java.util.HashSet; +import java.util.Set; + +/** + * Testing repository for managing tumor objects + */ +public class PlatformRepositoryTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(PlatformRepositoryTest.class); + private String extDsName = "TEST_SOURCE"; + private String extDsAbbrev = "TS"; + @Autowired + private PlatformRepository platformRepository; + + @Autowired + private PlatformAssociationRepository platformAssociationRepository; + + @Autowired + private GroupRepository groupRepository; + + @Autowired + private MarkerRepository markerRepository; + + @Before + public void cleanDb() { + + platformRepository.deleteAll(); + platformAssociationRepository.deleteAll(); + groupRepository.deleteAll(); + markerRepository.deleteAll(); + + Group ds = groupRepository.findByNameAndType(extDsName, "Provider"); + if(ds == null){ + log.info("Group not found. Creating", extDsName); + + ds = new Group(extDsName, extDsAbbrev, "Provider"); + groupRepository.save(ds); + + } + + } + + @Test + public void createPlatformAndAssociateMarkers() throws Exception { + + Set<PlatformAssociation> pas = new HashSet<>(); + + for (int i = 0; i < 10; i++) { + Marker marker = new Marker(); + marker.setHgncName("Marker" + i); + + PlatformAssociation p = new PlatformAssociation(); + p.setMarker(marker); + p.setExon("exon " + i); + pas.add(p); + + } + + Platform p = new Platform(); + p.setPlatformAssociations(pas); + p.setName("Gene Panel"); + p.setGroup(groupRepository.findByNameAndType(extDsName, "Provider")); + + platformRepository.save(p); + + assert (platformAssociationRepository.findByPlatform_ExternalDataSource_Name(extDsName).size() > 0); + assert platformRepository.findByName("Gene Panel").getPlatformAssociations().stream().count() > 5; + + + } + + +} diff --git a/data-model/src/test/java/org/pdxfinder/graph/repositories/SampleRepositoryTest.java b/data-model/src/test/java/org/pdxfinder/graph/repositories/SampleRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0d09e4239af9e0d6863886ac28d8947db4483c34 --- /dev/null +++ b/data-model/src/test/java/org/pdxfinder/graph/repositories/SampleRepositoryTest.java @@ -0,0 +1,145 @@ +package org.pdxfinder.graph.repositories; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.sql.Date; +import java.time.Instant; + +/** + * Testing repository for managing tumor objects + */ +public class SampleRepositoryTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(SampleRepositoryTest.class); + private String tumorTypeName = "TEST_TUMORTYPE"; + private String extDsName = "TEST_SOURCE"; + private String extDsAbbrev = "TS"; + private String tissueName = "TEST_TISSUE"; + + @Autowired + private SampleRepository sampleRepository; + + @Autowired + private TissueRepository tissueRepository; + + @Autowired + private TumorTypeRepository tumorTypeRepository; + + @Autowired + private PatientRepository patientRepository; + + @Autowired + private GroupRepository groupRepository; + + @Before + public void cleanDb() { + + sampleRepository.deleteAll(); + patientRepository.deleteAll(); + groupRepository.deleteAll(); + tissueRepository.deleteAll(); + + TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName); + if (tumorType == null) { + log.debug("Sample type {} not found. Creating", tumorTypeName); + tumorType = new TumorType(tumorTypeName); + tumorTypeRepository.save(tumorType); + } + + Group ds = groupRepository.findByNameAndType(extDsName, "Provider"); + if(ds == null){ + log.info("Group not found. Creating", extDsName); + + ds = new Group(extDsName, extDsAbbrev, "Provider"); + groupRepository.save(ds); + + } + + Tissue tissue = tissueRepository.findByName(tissueName); + if (tissue == null) { + log.debug("Tissue {} not found. Creating", extDsName); + tissue = new Tissue(tissueName); + tissueRepository.save(tissue); + } + + } + + @Test + public void createTumorInGraphDb() throws Exception { + + // Sample: + // String sourceTumorId + // TumorType type + // String diagnosis + // Tissue originTissue + // Tissue tumorSite + // String classification + // ExternalDataSource externalDataSource + + TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName); + Tissue tissue = tissueRepository.findByName(tissueName); + Group group = groupRepository.findByNameAndType(extDsName, "Provider"); + + String TEST_TUMOR_ID = "TESTID-1"; + generateTumor(tumorType, tissue, group, TEST_TUMOR_ID); + + Sample foundSample = sampleRepository.findBySourceSampleIdAndDataSource(TEST_TUMOR_ID, group.getAbbreviation()); + Assert.assertNotNull(foundSample); + + + } + + @Test + public void deleteTumor() throws Exception { + + TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName); + Tissue tissue = tissueRepository.findByName(tissueName); + Group ds = groupRepository.findByNameAndType(extDsName, "Provider"); + + String testTumorId = "DELETE_TESTID-1"; + generateTumor(tumorType, tissue, ds, testTumorId); + + Sample foundSample = sampleRepository.findBySourceSampleIdAndDataSource(testTumorId, ds.getAbbreviation()); + Assert.assertNotNull(foundSample); + + sampleRepository.delete(foundSample); + foundSample = sampleRepository.findBySourceSampleIdAndDataSource(testTumorId, ds.getAbbreviation()); + Assert.assertNull(foundSample); + } + + + @Test + public void deleteMultipleTumorsByDatasource() throws Exception { + + TumorType tumorType = tumorTypeRepository.findByName(tumorTypeName); + Tissue tissue = tissueRepository.findByName(tissueName); + Group ds = groupRepository.findByNameAndType(extDsName, "Provider"); + + for (Integer i = 0; i < 20; i++) { + String testTumorId = "TESTID-" + i; + generateTumor(tumorType, tissue, ds, testTumorId); + } + + Sample foundSample = sampleRepository.findBySourceSampleIdAndDataSource("TESTID-12", ds.getAbbreviation()); + Assert.assertNotNull(foundSample); + + // Added 20 tumors, count should be 20 + Assert.assertEquals(20, sampleRepository.count()); + + + } +//String sourceSampleId, TumorType type, String diagnosis, Tissue originTissue, Tissue sampleSite, String extractionMethod, String classification, Boolean normalTissue + private void generateTumor(TumorType tumorType, Tissue tissue, Group group, String TEST_TUMOR_ID) { + Sample sample = new Sample(TEST_TUMOR_ID, tumorType, "TEST_DIAGNOSIS", tissue, tissue, "Surgical Resection", "TEST_CLASSIFICATION", false, group.getAbbreviation()); + sampleRepository.save(sample); + } + + +} diff --git a/data-model/src/test/resources/logback.xml b/data-model/src/test/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..6a89304411c6f7825c0392d1c5b6318dc0e688c1 --- /dev/null +++ b/data-model/src/test/resources/logback.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <include resource="org/springframework/boot/logging/logback/base.xml"/> + <logger name="org.springframework" level="WARN"/> + <logger name="org.springframework.data.neo4j.mapping.Neo4jPersistentProperty" level="ERROR"/> + <logger name="org.neo4j" level="WARN"/> +</configuration> \ No newline at end of file diff --git a/indexer/src/test/resources/ogm.properties b/data-model/src/test/resources/ogm.properties similarity index 55% rename from indexer/src/test/resources/ogm.properties rename to data-model/src/test/resources/ogm.properties index a19ce84a6387ea17c01eedf517d270c3e287df72..e0d9ac7939a5d88c2fe886acb2cb2d0c94ee5640 100644 --- a/indexer/src/test/resources/ogm.properties +++ b/data-model/src/test/resources/ogm.properties @@ -1 +1,4 @@ +# +# Configuration for embedded neo4j for tests +# driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver diff --git a/data-services/pom.xml b/data-services/pom.xml index ce9ca9623755b0398334c4f244c547c5b61e3324..d61dc5f0278111a26dae972db21171305679921f 100644 --- a/data-services/pom.xml +++ b/data-services/pom.xml @@ -23,15 +23,16 @@ </dependency> <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-core</artifactId> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> - <groupId>com.h2database</groupId> - <artifactId>h2</artifactId> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> </dependency> + <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-csv</artifactId> @@ -42,13 +43,6 @@ <artifactId>jackson-databind</artifactId> </dependency> - <dependency> - <groupId>org.neo4j</groupId> - <artifactId>neo4j-ogm-embedded-driver</artifactId> - <scope>test</scope> - <version>2.1.1</version> - </dependency> - <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> @@ -61,26 +55,25 @@ <version>3.3.0</version> </dependency> - <!-- For loading excel documents --> - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi-ooxml</artifactId> - <version>3.15</version> - </dependency> - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi</artifactId> - <version>3.15</version> - </dependency> - <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.4.2</version> </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-embedded-driver</artifactId> + <version>3.1.20</version> + <scope>test</scope> + </dependency> + <dependency> + <!-- WARNING, do not update db engine (stable: 1.4.197) cause compatibility issues, see https://github.com/h2database/h2database/issues/2078 --> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>1.4.197</version> + </dependency> </dependencies> - </project> \ No newline at end of file diff --git a/data-services/src/main/java/org/pdxfinder/services/AutoCompleteService.java b/data-services/src/main/java/org/pdxfinder/services/AutoCompleteService.java index 3448d647dc4e1f5cc6e7a5b0abf857aec159db18..e35a9e0931a3b6111365f0a0f5445db1444a79eb 100644 --- a/data-services/src/main/java/org/pdxfinder/services/AutoCompleteService.java +++ b/data-services/src/main/java/org/pdxfinder/services/AutoCompleteService.java @@ -1,17 +1,11 @@ package org.pdxfinder.services; -import org.pdxfinder.graph.dao.DataProjection; import org.pdxfinder.graph.dao.OntologyTerm; -import org.pdxfinder.graph.repositories.DataProjectionRepository; import org.pdxfinder.graph.repositories.OntologyTermRepository; import org.pdxfinder.services.ds.AutoCompleteOption; -import org.pdxfinder.services.ds.ModelForQuery; -import org.pdxfinder.services.ds.SearchDS; import org.springframework.stereotype.Service; - import java.util.*; -import java.util.stream.Collectors; /* * Created by csaba on 05/02/2018. @@ -139,7 +133,6 @@ public class AutoCompleteService { Set<String> termsToRemove = new HashSet<>(Arrays.asList(doNotDisplay)); - Collection<OntologyTerm> ontologyTerms = ontologyTermRepository.findAllWithMappings(); List<String> autoSuggestList = new ArrayList<>(); @@ -157,142 +150,9 @@ public class AutoCompleteService { } Collections.sort(autoSuggestList); - return autoSuggestList; - } - - public List<String> getAutoSuggestions(List<String> ids){ - String[] doNotDisplay = {"Neoplasm by Morphology", - "Neoplasm by Site", - "Glandular Cell Neoplasm", - "Digestive System Neoplasm", - "Intestinal Neoplasm", - "Colorectal Neoplasm", - "Melanocytic Neoplasm", - "Respiratory Tract Neoplasm", - "Thoracic Neoplasm", - "Lung Neoplasm", - "Breast Neoplasm", - "Colon Neoplasm", - "Skin Neoplasm", - "Melanocytic Skin Neoplasm", - "Urinary System Neoplasm", - "Nervous System Neoplasm", - "Central Nervous System Neoplasm", - "Astrocytic Tumor", - "Bladder Neoplasm", - "Pancreatic Neoplasm", - "Bone Marrow Neoplasm", - "Pancreatic Exocrine Neoplasm", - "Breast Carcinoma by Gene Expression Profile", - "Reproductive System Neoplasm", - "Endocrine Neoplasm", - "Myomatous Neoplasm", - "Female Reproductive System Neoplasm", - "Sarcoma by NCI Grade", - "Sarcoma NCI Grade 3", - "Ovarian Neoplasm", - "Ovarian Epithelial Tumor", - "Head and Neck Neoplasm", - "Bone Neoplasm", - "Skeletal Muscle Neoplasm", - "Ovarian Serous Tumor", - "Sarcoma by FNCLCC Grade", - "FNCLCC Sarcoma Grade 3", - "Kidney and Ureter Neoplasm", - "Kidney Neoplasm", - "Rectal Neoplasm", - "Smooth Muscle Neoplasm", - "Soft Tissue Neoplasm", - "Hepatobiliary Neoplasm", - "Intraductal Breast Neoplasm", - "Ampulla of Vater Neoplasm", - "Intraepithelial Neoplasia", - "Eye Neoplasm", - "Male Reproductive System Neoplasm", - "Uterine Neoplasm", - "Glandular Cell Intraepithelial Neoplasia", - "High Grade Glandular Intraepithelial Neoplasia", - "Uterine Corpus Neoplasm", - "Uveal Neoplasm", - "Grade III Glandular Intraepithelial Neoplasia", - "Soft Tissue Tumor of Uncertain Differentiation", - "Malignant Soft Tissue Tumor of Uncertain Differentiation", - "Cecum Neoplasm", - "Breast Cancer by AJCC v6 Stage", - "Breast Cancer by AJCC v7 Stage", - "Stage 0 Breast Cancer AJCC v6 and v7", - "High Grade Intraepithelial Neoplasia", - "Neck Neoplasm", - "Salivary Gland Neoplasm", - "Acute Myeloid Leukemia Not Otherwise Specified", - "Lipomatous Neoplasm", - "Prostate Neoplasm", - "Appendix Neoplasm", - "Gastric Neoplasm", - "Anal Neoplasm", - "Intraductal Proliferative Lesion of the Breast", - "Intraductal Papillary Breast Neoplasm", - "Breast Cancer by AJCC v8 Stage", - "Breast Cancer by AJCC v8 Anatomic Stage", - "Anatomic Stage 0 Breast Cancer AJCC v8", - "Pharyngeal Neoplasm", - "Oropharyngeal Neoplasm", - "Tonsillar Neoplasm", - "Liver and Intrahepatic Bile Duct Epithelial Neoplasm", - "Malignant Mesothelioma", - "Peritoneal and Retroperitoneal Neoplasms", - "Peripheral Nervous System Neoplasm", - "Intracranial Neoplasm", - "Oral Neoplasm", - "Mixed Mesodermal (Mullerian) Tumor", - "Brain Neoplasm", - "Retroperitoneal Neoplasm", - "Nerve Sheath Neoplasm", - "Stromal Neoplasm", - "Chondrogenic Neoplasm", - "Lobular Neoplasia", - "Primary Brain Neoplasm", - "Testicular Neoplasm", - "Esophageal Neoplasm", - "Oral Cavity Neoplasm", - "Small Intestinal Neoplasm", - "Duodenal Neoplasm", - "Glioblastoma, IDH-Wildtype", - "Uterine Corpus Smooth Muscle Neoplasm", - "Testicular Germ Cell Tumor", - "Testicular Pure Germ Cell Tumor", - "Testicular Non-Seminomatous Germ Cell Tumor", - "Adult Acute Lymphoblastic Leukemia", - "Adrenal Gland Neoplasm", - "Adrenal Medulla Neoplasm", - "Childhood Kidney Neoplasm", - "Tongue Neoplasm"}; - - Set<String> termsToRemove = new HashSet<>(Arrays.asList(doNotDisplay)); - - - Collection<OntologyTerm> ontologyTerms = ontologyTermRepository.findAllWithMappings(); - - List<String> autoSuggestList = new ArrayList<>(); - - for (OntologyTerm ontologyTerm : ontologyTerms) { - if (ontologyTerm.getLabel() != null) { - - if(!termsToRemove.contains(ontologyTerm.getLabel()) || ontologyTerm.getDirectMappedSamplesNumber() > 0){ - - //autoSuggestList.add(new AutoCompleteOption(ontologyTerm.getLabel(), "OntologyTerm")); - autoSuggestList.add(ontologyTerm.getLabel()); - } - - } - } - - Collections.sort(autoSuggestList); - autoSuggestList.addAll(ids); return autoSuggestList; } - } diff --git a/data-services/src/main/java/org/pdxfinder/services/DataImportService.java b/data-services/src/main/java/org/pdxfinder/services/DataImportService.java index 60a5ad5d44f69a4e8452d999823807c60cab23cc..12e73337b491cc8e79ae39df50a747b24fdabe12 100644 --- a/data-services/src/main/java/org/pdxfinder/services/DataImportService.java +++ b/data-services/src/main/java/org/pdxfinder/services/DataImportService.java @@ -1,10 +1,9 @@ package org.pdxfinder.services; +import com.github.openjson.JSONArray; +import com.github.openjson.JSONObject; import org.apache.commons.lang3.StringUtils; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; import org.pdxfinder.graph.dao.*; -import org.pdxfinder.graph.queryresults.MutatedMarkerData; import org.pdxfinder.graph.queryresults.TreatmentMappingData; import org.pdxfinder.graph.repositories.*; import org.pdxfinder.services.ds.Standardizer; @@ -16,8 +15,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.util.Assert; -import org.springframework.cache.annotation.Cacheable; - import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -53,7 +50,6 @@ public class DataImportService { private TreatmentProtocolRepository treatmentProtocolRepository; private CurrentTreatmentRepository currentTreatmentRepository; private ExternalUrlRepository externalUrlRepository; - private DrugRepository drugRepository; private TreatmentRepository treatmentRepository; private final static Logger log = LoggerFactory.getLogger(DataImportService.class); @@ -88,7 +84,6 @@ public class DataImportService { TreatmentProtocolRepository treatmentProtocolRepository, CurrentTreatmentRepository currentTreatmentRepository, ExternalUrlRepository externalUrlRepository, - DrugRepository drugRepository, TreatmentRepository treatmentRepository) { Assert.notNull(tumorTypeRepository, "tumorTypeRepository cannot be null"); @@ -131,7 +126,6 @@ public class DataImportService { this.treatmentProtocolRepository = treatmentProtocolRepository; this.currentTreatmentRepository = currentTreatmentRepository; this.externalUrlRepository = externalUrlRepository; - this.drugRepository = drugRepository; this.treatmentRepository = treatmentRepository; @@ -141,20 +135,6 @@ public class DataImportService { } - public Group getGroup(String name, String abbrev, String type){ - - Group g = groupRepository.findByNameAndType(name, type); - - if(g == null){ - log.info("Group not found. Creating {}", name); - - g = new Group(name, abbrev, type); - groupRepository.save(g); - - } - - return g; - } public Group getProviderGroup(String name, String abbrev, String description, String providerType, String contact, String url){ @@ -299,10 +279,6 @@ public class DataImportService { return modelCreationRepository.findAllModelsPlatforms(); } - public int countMarkerAssociationBySourcePdxId(String modelId, String dataSource, String platformName){ - - return modelCreationRepository.countMarkerAssociationBySourcePdxId(modelId, dataSource, platformName); - } public Collection<ModelCreation> findModelsWithPatientData(){ @@ -324,9 +300,17 @@ public class DataImportService { return modelCreationRepository.findModelPlatformSampleByDS(ds); } - public ModelCreation findModelWithMolecularDataByDSAndIdAndMolcharType(String dataSource, String modelId, String molcharType){ + public List<ModelCreation> findModelsWithMolecularDataByDSAndMolcharType(String dataSource, String molcharType){ + + return modelCreationRepository.findModelsWithMolecularDataByDSAndMolcharType(dataSource, molcharType); + } + + public List<ModelCreation> findModelsWithTreatmentSummaryByDS(String datasource){ + return modelCreationRepository.findModelsWithTreatmentSummaryByDataSource(datasource); + } - return modelCreationRepository.findModelWithMolecularDataByDSAndIdAndMolcharType(dataSource, modelId, molcharType); + public List<ModelCreation> findModelFromPatienSnapshotWithTreatmentSummaryByDS(String datasource){ + return modelCreationRepository.findModelFromPatienSnapshotWithTreatmentSummaryByDataSource(datasource); } public List<ModelCreation> findModelsWithSharingAndContactByDS(String ds){ @@ -363,10 +347,6 @@ public class DataImportService { return modelCreationRepository.findModelWithSampleByMolChar(mc); } - public int getModelCount(){ - - return modelCreationRepository.countAllModels(); - } public int getModelCountByDataSource(String dataSource){ @@ -518,24 +498,6 @@ public class DataImportService { return ps; } - - - public Patient getPatient(String externalId, String sex, String race, String ethnicity, Group group) { - - Patient patient = patientRepository.findByExternalIdAndGroup(externalId, group); - - if (patient == null) { - log.info("Patient '{}' not found. Creating", externalId); - - patient = new Patient(externalId, sex, race, ethnicity, group); - - patientRepository.save(patient); - } - - return patient; - } - - public Sample getSample(String sourceSampleId, String typeStr, String diagnosis, String originStr, String sampleSiteStr, String extractionMethod, String classification, Boolean normalTissue, String dataSource) { TumorType type = this.getTumorType(typeStr); @@ -597,44 +559,6 @@ public class DataImportService { } - - public Sample findSampleByDataSourceAndSourceSampleId(String dataSource, String sampleId){ - - return sampleRepository.findBySourceSampleIdAndDataSource(sampleId, dataSource); - } - - public Collection<Sample> findSamplesWithoutOntologyMapping(){ - - return sampleRepository.findSamplesWithoutOntologyMapping(); - } - - public Sample getMouseSample(ModelCreation model, String specimenId, String dataSource, String passage, String sampleId){ - - Specimen specimen = this.getSpecimen(model, specimenId, dataSource, passage); - Sample sample; - - if(specimen.getSample() == null){ - sample = new Sample(); - sample.setSourceSampleId(sampleId); - sample.setDataSource(dataSource); - sampleRepository.save(sample); - } - else{ - - sample = specimen.getSample(); - } - - return sample; - } - - //public findSampleWithMolcharBySpecimen - - - public Sample findMouseSampleWithMolcharByModelIdAndDataSourceAndSampleId(String modelId, String dataSource, String sampleId){ - - return sampleRepository.findMouseSampleWithMolcharByModelIdAndDataSourceAndSampleId(modelId, dataSource, sampleId); - } - public Sample findHumanSampleWithMolcharByModelIdAndDataSource(String modelId, String dataSource){ return sampleRepository.findHumanSampleWithMolcharByModelIdAndDataSource(modelId, dataSource); @@ -658,30 +582,12 @@ public class DataImportService { return molecularCharacterizationRepository.findByIds(ids); } - public Sample getHumanSample(String sampleId, String dataSource){ - - - return sampleRepository.findHumanSampleBySampleIdAndDataSource(sampleId, dataSource); - } - public Sample findHumanSample(String modelId, String dsAbbrev){ return sampleRepository.findHumanSampleByModelIdAndDS(modelId, dsAbbrev); } - public Sample findXenograftSample(String modelId, String dataSource, String specimenId){ - - return sampleRepository.findMouseSampleByModelIdAndDataSourceAndSpecimenId(modelId, dataSource, specimenId); - } - - public Sample findXenograftSample(String modelId, String dataSource, String passage, String nomenclature){ - - - return sampleRepository.findMouseSampleByModelIdAndDataSourceAndPassageAndNomenclature(modelId, dataSource, passage, nomenclature); - } - - public int getHumanSamplesNumber(){ return sampleRepository.findHumanSamplesNumber(); @@ -789,12 +695,6 @@ public class DataImportService { return hostStrain; } - public HostStrain findHostStrain(String symbol){ - - return hostStrainRepository.findBySymbol(symbol); - } - - // is this bad? ... probably.. public Marker getMarker(String symbol) { log.error("MARKER METHOD WAS CALLED!"); @@ -815,11 +715,6 @@ public class DataImportService { return marker; } - public List<MutatedMarkerData> getFrequentlyMutatedGenes(){ - - return markerRepository.countModelsByMarker(); - } - public Set<MarkerAssociation> findMarkerAssocsByMolChar(MolecularCharacterization mc){ return markerAssociationRepository.findByMolChar(mc); @@ -837,9 +732,13 @@ public class DataImportService { return molecularCharacterizationRepository.save(mc); } + public void saveMolecularCharacterizations(List<MolecularCharacterization> mc){ + molecularCharacterizationRepository.saveAll(mc); + } + public void saveQualityAssurance(QualityAssurance qa) { if (qa != null) { - if (null == qualityAssuranceRepository.findFirstByTechnologyAndDescription(qa.getTechnology(), qa.getDescription())) { + if (null == qualityAssuranceRepository.findByTechnologyAndDescriptionAndPassage(qa.getTechnology(), qa.getDescription(), qa.getPassages())) { qualityAssuranceRepository.save(qa); } } @@ -850,12 +749,6 @@ public class DataImportService { return molecularCharacterizationRepository.findAllByType(type); } - - public List<Specimen> findSpecimenByPassage(ModelCreation model, String passage){ - - return specimenRepository.findByModelIdAndDataSourceAndAndPassage(model.getSourcePdxId(), model.getDataSource(), passage); - } - public Specimen getSpecimen(ModelCreation model, String specimenId, String dataSource, String passage){ Specimen specimen = specimenRepository.findByModelIdAndDataSourceAndSpecimenIdAndPassage(model.getSourcePdxId(), dataSource, specimenId, passage); @@ -877,13 +770,6 @@ public class DataImportService { return specimenRepository.findByModelAndPassageAndNomenClature(modelCreation, passage, nomenclature); } - - public List<Specimen> getAllSpecimenByModel(String modelId, String dataSource){ - - return specimenRepository.findByModelIdAndDataSource(modelId, dataSource); - } - - public Specimen findSpecimenByMolChar(MolecularCharacterization mc){ return specimenRepository.findByMolChar(mc); @@ -910,10 +796,6 @@ public class DataImportService { return ontologyTermRepository.findByUrl(url); } - public OntologyTerm findOntologyTermByLabel(String label){ - return ontologyTermRepository.findByLabel(label); - } - public OntologyTerm findOntologyTermByLabelAndType(String label, String type){ return ontologyTermRepository.findByLabelAndType(label, type); } @@ -923,12 +805,6 @@ public class DataImportService { return ontologyTermRepository.findByUrl(url); } - public Collection<OntologyTerm> getAllOntologyTerms() { - - return ontologyTermRepository.findAll(); - - } - public Collection<OntologyTerm> getAllOntologyTermsWithNotZeroDirectMapping(){ return ontologyTermRepository.findAllWithNotZeroDirectMappingNumber(); @@ -939,28 +815,6 @@ public class DataImportService { return ontologyTermRepository.findAllDirectParents(termUrl); } - public int getIndirectMappingNumber(String label) { - - return ontologyTermRepository.getIndirectMappingNumber(label); - } - - public int findDirectMappingNumber(String label) { - - - Set<OntologyTerm> otset = ontologyTermRepository.getDistinctSubTreeNodes(label); - int mapNum = 0; - for (OntologyTerm ot : otset) { - mapNum += ot.getDirectMappedSamplesNumber(); - } - return mapNum; - } - - public Collection<OntologyTerm> getAllOntologyTermsFromTo(int from, int to) { - - return ontologyTermRepository.findAllFromTo(from, to); - - } - public Collection<OntologyTerm> getAllOntologyTermsByTypeFromTo(String type, int from, int to) { return ontologyTermRepository.findAllByTypeFromTo(type, from, to); @@ -1003,11 +857,7 @@ public class DataImportService { } public void saveAllMarkers(Collection<Marker> markers) { - markerRepository.save(markers); - } - - public Collection<Marker> getAllMarkers() { - return markerRepository.findAllMarkers(); + markerRepository.saveAll(markers); } public Integer countAllMarkers() { @@ -1022,11 +872,6 @@ public class DataImportService { return markerRepository.findAllHumanMarkers(); } - public Set<Marker> findAllDistinctMarkersByMolCharId(Long id){ - - return markerRepository.findDistinctByMolCharId(id); - } - public Platform getPlatform(String name, String type, Group group) { //remove special characters from platform name @@ -1095,13 +940,9 @@ public class DataImportService { return pa; } - public void savePlatformAssociation(PlatformAssociation pa){ - platformAssociationRepository.save(pa); - } - - public void saveDataProjection(DataProjection dp){ + public DataProjection saveDataProjection(DataProjection dp){ - dataProjectionRepository.save(dp); + return dataProjectionRepository.save(dp); } public DataProjection findDataProjectionByLabel(String label){ @@ -1138,21 +979,6 @@ public class DataImportService { } - public int findModelTreatmentNumber(String dataSource){ - - if(dataSource == null || dataSource.isEmpty()){ - - return treatmentRepository.findModelTreatmentNumber(); - } - else{ - - return treatmentRepository.findModelTreatmentNumberByDS(dataSource); - } - - - } - - public Collection<Treatment> getPatientTreatmentFrom(int from, int batch, String dataSource){ if(dataSource == null || dataSource.isEmpty()){ @@ -1163,8 +989,6 @@ public class DataImportService { return treatmentRepository.getPatientTreatmentFromByDS(from, batch, dataSource); } - - } @@ -1178,7 +1002,6 @@ public class DataImportService { return treatmentRepository.getModelTreatmentFromByDS(from, batch, dataSource); } - } @@ -1231,12 +1054,6 @@ public class DataImportService { return ct; } - - public void createDrug(Drug d){ - drugRepository.save(d); - } - - /** * * @param drugString @@ -1390,37 +1207,11 @@ public class DataImportService { } - - - - public TreatmentSummary findTreatmentSummaryByPatientSnapshot(PatientSnapshot ps){ return treatmentSummaryRepository.findByPatientSnapshot(ps); - - } - - - - - - public Set<Object> findUnlinkedNodes(){ - - return dataProjectionRepository.findUnlinkedNodes(); - } - - public Set<Object> findPatientsWithMultipleSummaries(){ - - return dataProjectionRepository.findPatientsWithMultipleTreatmentSummaries(); } - public Set<Object> findPlatformsWithoutUrl(){ - - return dataProjectionRepository.findPlatformsWithoutUrl(); - } - - - public QualityAssurance getQualityAssurance(JSONObject data, String ds) throws Exception{ QualityAssurance qa = new QualityAssurance(); @@ -1512,24 +1303,6 @@ public class DataImportService { return qa; } - @Cacheable - public Marker getMarkerBySymbol(String symbol){ - - return markerRepository.findBySymbol(symbol); - } - - @Cacheable - public List<Marker> getMarkerByPrevSymbol(String symbol){ - - return markerRepository.findByPrevSymbol(symbol); - } - - @Cacheable - public List<Marker> getMarkerBySynonym(String symbol){ - - return markerRepository.findBySynonym(symbol); - } - private void initializeMarkers(){ int markerCount = markerRepository.getMarkerCount(); diff --git a/data-services/src/main/java/org/pdxfinder/services/DetailsService.java b/data-services/src/main/java/org/pdxfinder/services/DetailsService.java index 52926a22cb879ab67c29acdcf4906271024fca6c..6e62c2abb62b92255330661fb7467df2741737c0 100644 --- a/data-services/src/main/java/org/pdxfinder/services/DetailsService.java +++ b/data-services/src/main/java/org/pdxfinder/services/DetailsService.java @@ -1,15 +1,13 @@ package org.pdxfinder.services; -import org.apache.commons.collections4.ListUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.text.WordUtils; import org.pdxfinder.graph.dao.*; import org.pdxfinder.graph.repositories.*; import org.pdxfinder.services.dto.*; import org.pdxfinder.services.dto.pdxgun.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Sort; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; @@ -27,17 +25,14 @@ public class DetailsService { private SampleRepository sampleRepository; private PatientRepository patientRepository; - private PatientSnapshotRepository patientSnapshotRepository; + private ModelCreationRepository modelCreationRepository; private SpecimenRepository specimenRepository; private MolecularCharacterizationRepository molecularCharacterizationRepository; private PlatformRepository platformRepository; private TreatmentSummaryRepository treatmentSummaryRepository; - private MarkerAssociationRepository markerAssociationRepository; - private GraphService graphService; - private Map<String, List<String>> facets = new HashMap<>(); - private PlatformService platformService; + private DrugService drugService; private PatientService patientService; private PublicationService publicationService; @@ -45,36 +40,30 @@ public class DetailsService { private final static Logger log = LoggerFactory.getLogger(DetailsService.class); private ReferenceDbService referenceDbService; - + @Autowired public DetailsService(SampleRepository sampleRepository, PatientRepository patientRepository, - PatientSnapshotRepository patientSnapshotRepository, + ModelCreationRepository modelCreationRepository, SpecimenRepository specimenRepository, MolecularCharacterizationRepository molecularCharacterizationRepository, PlatformRepository platformRepository, TreatmentSummaryRepository treatmentSummaryRepository, - GraphService graphService, - PlatformService platformService, DrugService drugService, PatientService patientService, - MarkerAssociationRepository markerAssociationRepository, PublicationService publicationService, ReferenceDbService referenceDbService) { this.sampleRepository = sampleRepository; this.patientRepository = patientRepository; - this.patientSnapshotRepository = patientSnapshotRepository; + this.modelCreationRepository = modelCreationRepository; this.molecularCharacterizationRepository = molecularCharacterizationRepository; this.specimenRepository = specimenRepository; this.platformRepository = platformRepository; this.treatmentSummaryRepository = treatmentSummaryRepository; - this.graphService = graphService; - this.platformService = platformService; this.drugService = drugService; this.patientService = patientService; - this.markerAssociationRepository = markerAssociationRepository; this.publicationService = publicationService; this.referenceDbService = referenceDbService; @@ -352,17 +341,7 @@ public class DetailsService { mde.setDataAvailableLabel(mc.getPlatform().getName()); mde.setDataAvailableUrl(""); mde.setPlatformUsedLabel(mc.getPlatform().getName()); - - // mde.setPlatformUsedUrl(mc.getPlatform().getUrl()); - - // temp solution, ToDo: solve properly via appropriate url redirection - /platform/sth/ -> /platform/sth - String auxStr = mc.getPlatform().getUrl(); - if (auxStr != null && auxStr.length() > 1 && auxStr.charAt(auxStr.length() - 1) == '/') { - auxStr = auxStr.substring(0, auxStr.length() - 1); - } - mde.setPlatformUsedUrl(auxStr); - - mde.setRawDataLabel("Not available"); + mde.setPlatformUsedUrl(mc.getPlatform().getUrl()); mde.setMolcharId(mc.getId().toString()); setRawDataLabelAndLink(mde, xenoSample); @@ -419,10 +398,14 @@ public class DetailsService { } - public MolecularDataTableDTO getMolecularDataTable(String id){ + public MolecularCharacterization getMolcharData(String id){ + return molecularCharacterizationRepository.getMolecularDataById(Long.valueOf(id)); + } + + public MolecularDataTableDTO getMolecularDataTable(String id, boolean forceReturn){ MolecularDataTableDTO dto = new MolecularDataTableDTO(); - MolecularCharacterization mc = molecularCharacterizationRepository.getMolecularDataById(Long.valueOf(id)); + MolecularCharacterization mc = getMolcharData(id); if(mc == null){ @@ -439,6 +422,15 @@ public class DetailsService { dto.setMolecularDataRows(new ArrayList<>()); return dto; } + else if(mc.getFirstMarkerAssociation() != null && mc.getFirstMarkerAssociation().getDataPoints() > 300 && !forceReturn){ + + List<String> dataRow = new ArrayList<>(); + dataRow.add("This dataset is too big to display, please click on the download results button to view data."); + dto.setVisible(true); + dto.setReports(dataRow); + dto.setMolecularDataRows(new ArrayList<>()); + return dto; + } else { Sample sample = sampleRepository.findSampleByMolcharId(Long.valueOf(id)); diff --git a/data-services/src/main/java/org/pdxfinder/services/EmailService.java b/data-services/src/main/java/org/pdxfinder/services/EmailService.java index 8562a06385b3ec5600c7f3c57ac43d32bb0c7318..fb19d781ce6f6c98beace05384b510f0b36d1e8f 100644 --- a/data-services/src/main/java/org/pdxfinder/services/EmailService.java +++ b/data-services/src/main/java/org/pdxfinder/services/EmailService.java @@ -1,6 +1,5 @@ package org.pdxfinder.services; -import org.neo4j.cypher.internal.frontend.v2_3.ast.functions.Str; import org.pdxfinder.services.email.Mail; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,7 +9,7 @@ import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.thymeleaf.context.Context; -import org.thymeleaf.spring4.SpringTemplateEngine; +import org.thymeleaf.spring5.SpringTemplateEngine; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; @@ -50,7 +49,7 @@ public class EmailService { mail.setSubject(subject); - Map<String, Object> model = new HashMap<String, Object>(); + Map<String, Object> model = new HashMap<>(); model.put("date", "xxxx"); model.put("count", missingCount); mail.setModel(model); diff --git a/data-services/src/main/java/org/pdxfinder/services/GraphService.java b/data-services/src/main/java/org/pdxfinder/services/GraphService.java index 078446482eb244ee887e822a5bc1639bbb283080..77b4291bc2d60dc9b060489d302af4bcd52953b1 100644 --- a/data-services/src/main/java/org/pdxfinder/services/GraphService.java +++ b/data-services/src/main/java/org/pdxfinder/services/GraphService.java @@ -1,7 +1,7 @@ package org.pdxfinder.services; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.JSONArray; +import com.github.openjson.JSONObject; import org.pdxfinder.graph.dao.DataProjection; import org.pdxfinder.graph.dao.OntologyTerm; import org.pdxfinder.graph.dao.Sample; diff --git a/data-services/src/main/java/org/pdxfinder/services/MappingService.java b/data-services/src/main/java/org/pdxfinder/services/MappingService.java index d2b2f0cead5f6a11e287f7f251ff220571d1b3db..9b769e41276e254b428f22bff79ff91b617c8a7b 100644 --- a/data-services/src/main/java/org/pdxfinder/services/MappingService.java +++ b/data-services/src/main/java/org/pdxfinder/services/MappingService.java @@ -3,19 +3,18 @@ package org.pdxfinder.services; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.Gson; +import com.github.openjson.JSONArray; +import com.github.openjson.JSONException; +import com.github.openjson.JSONObject; import org.apache.commons.lang3.StringUtils; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONException; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.services.mapping.MappingContainer; import org.pdxfinder.graph.dao.OntologyTerm; import org.pdxfinder.graph.repositories.OntologyTermRepository; -import org.pdxfinder.rdbms.dao.MappingEntity; import org.pdxfinder.graph.repositories.SampleRepository; +import org.pdxfinder.rdbms.dao.MappingEntity; import org.pdxfinder.rdbms.repositories.MappingEntityRepository; import org.pdxfinder.services.dto.PaginationDTO; import org.pdxfinder.services.mapping.CSV; +import org.pdxfinder.services.mapping.MappingContainer; import org.pdxfinder.services.mapping.MappingEntityType; import org.pdxfinder.services.mapping.Status; import org.pdxfinder.services.zooma.*; @@ -31,7 +30,10 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; -import java.io.*; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @@ -55,7 +57,6 @@ public class MappingService { @Value("${data-dir}") private String rootDir; - @Value("${mappings.mappedTermUrl}") private String knowledgBaseURL; @@ -122,10 +123,7 @@ public class MappingService { Map<String, List<MappingEntity>> mappings = new HashMap<>(); mappings.put("mappings", maprules); - Gson gson = new Gson(); - String json = gson.toJson(mappings); - - + String json = JSONObject.wrap(mappings).toString(); try { BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, false)); @@ -664,7 +662,9 @@ public class MappingService { for (String mappingLabel : mappingLabels) { /* ZOOMA PROPERTY DATA */ - Property property = new Property(mappingLabel, StringUtils.upperCase(mappingValues.get(mappingLabel))); + Property property = new org.pdxfinder.services.zooma.Property( + mappingLabel, + StringUtils.upperCase(mappingValues.get(mappingLabel))); List<String> annotations = new ArrayList<>(); @@ -809,36 +809,42 @@ public class MappingService { public void writeMappingsToFile(String entityType) { + if (!containsSpecialCharacters(entityType)) throw new IllegalArgumentException("EntityType contains illegal characters"); + else { + String jsonKey = "mappings"; + String mappingFile = rootDir + "/mapping/" + entityType + "_mappings.json"; - String jsonKey = "mappings"; - - String mappingFile = rootDir + "/mapping/" + entityType + "_mappings.json"; - - // Generate Unique name to back up previous mapping file - String backupPreviousMappingFile = rootDir + "/mapping/backup/" + entityType + "/" + - (new Date()).toString().replaceAll(" ", "-") + "-" + entityType + "_mappings.json"; + // Generate Unique name to back up previous mapping file + String baseDirectory = rootDir + "/mapping/backup/"; + String backupPreviousMappingFile = baseDirectory + entityType + "/" + + (new Date()).toString().replaceAll(" ", "-") + "-" + entityType + "_mappings.json"; - // Back up previous mapping file before replacement - utilityService.moveFile(mappingFile, backupPreviousMappingFile); + // Back up previous mapping file before replacement + utilityService.moveFile(mappingFile, backupPreviousMappingFile); - // Get Latest mapped terms from the data base - List<MappingEntity> mappingEntities = mappingEntityRepository.findByEntityTypeAndStatusIsNot(entityType, "unmapped"); - Map dataMap = new HashMap(); + // Get Latest mapped terms from the data base + List<MappingEntity> mappingEntities = mappingEntityRepository.findByEntityTypeAndStatusIsNot(entityType, "unmapped"); - dataMap.put(jsonKey, mappingEntities); + Map dataMap = new HashMap(); + dataMap.put(jsonKey, mappingEntities); - // Write latest mapped terms to the file system - try { + // Write latest mapped terms to the file system + try { - String newFile = mapper.writeValueAsString(dataMap); - utilityService.writeToFile(newFile, mappingFile, false); + String newFile = mapper.writeValueAsString(dataMap); + utilityService.writeToFile(newFile, mappingFile, false); - } catch (JsonProcessingException e) { + } catch (JsonProcessingException e) { + } } } + private boolean containsSpecialCharacters(String input){ + return input.matches("^[A-Za-z0-9-_]*$"); + } + public PaginationDTO search(int page, int size, @@ -861,7 +867,9 @@ public class MappingService { // requested page is either +ve or forced to default page int start = (page > 0) ? page - 1 : 0; - pageable = new PageRequest(start, size, direction, sortColumn); + Sort sort = Sort.by(direction, sortColumn); + + pageable = PageRequest.of(start, size, sort); Page<MappingEntity> mappingEntityPage = mappingEntityRepository.findByMultipleFilters(entityType, mappingLabel, mappingValue, mappedTermLabel, mapType, mappedTermsOnly, status, pageable); @@ -952,7 +960,7 @@ public class MappingService { public boolean checkExistence(Long entityId) { - return mappingEntityRepository.exists(entityId); + return mappingEntityRepository.existsByEntityId(entityId); } @@ -1049,11 +1057,10 @@ public class MappingService { }); return savedEntities; - } - - - + public void setRootDir(String rootDir) { + this.rootDir = rootDir; + } } diff --git a/data-services/src/main/java/org/pdxfinder/services/OmicTransformationService.java b/data-services/src/main/java/org/pdxfinder/services/OmicTransformationService.java index f29ba339c33a627e6af372860c1f0529dc3cc5a1..7101769bd02bd01e5da1936d270351bb90a7f4bc 100644 --- a/data-services/src/main/java/org/pdxfinder/services/OmicTransformationService.java +++ b/data-services/src/main/java/org/pdxfinder/services/OmicTransformationService.java @@ -63,13 +63,18 @@ public class OmicTransformationService { } public String ncbiGeneIdToHgncSymbol(String ncbiGene) { - String hgncSymbol = geneIdCache.get(ncbiGene); - if (hgncSymbol == null) { - Marker marker = dataImportService.getMarkerbyNcbiGeneId(ncbiGene); - if (marker.hasHgncSymbol()) { - hgncSymbol = marker.getHgncSymbol(); - geneIdCache.put(ncbiGene, hgncSymbol); - } else { log.warn("No marker found for NCBI gene Id {} Cannot generate Hgnc symbol", ncbiGene); } + String hgncSymbol = ""; + if (!ncbiGene.isEmpty()) { + hgncSymbol = geneIdCache.get(ncbiGene); + if (hgncSymbol == null) { + Marker marker = dataImportService.getMarkerbyNcbiGeneId(ncbiGene); + if (marker != null && marker.hasHgncSymbol()) { + hgncSymbol = marker.getHgncSymbol(); + geneIdCache.put(ncbiGene, hgncSymbol); + } else { + log.warn("No marker found for NCBI gene Id {} Cannot generate Hgnc symbol", ncbiGene); + } + } } return hgncSymbol; } diff --git a/data-services/src/main/java/org/pdxfinder/services/PlatformService.java b/data-services/src/main/java/org/pdxfinder/services/PlatformService.java index 190d1c6b17b23f65be615406a01c0f1a5f0fcef5..fae5f001e63c1fd68d85a2c8d604b47955b40371 100644 --- a/data-services/src/main/java/org/pdxfinder/services/PlatformService.java +++ b/data-services/src/main/java/org/pdxfinder/services/PlatformService.java @@ -1,7 +1,6 @@ package org.pdxfinder.services; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.*; import org.pdxfinder.graph.repositories.DataProjectionRepository; import org.pdxfinder.graph.repositories.ModelCreationRepository; diff --git a/data-services/src/main/java/org/pdxfinder/services/PublicationService.java b/data-services/src/main/java/org/pdxfinder/services/PublicationService.java index 4e8e7adf628e739789f14765ffbb35edcd132b93..ee0631bcaddaf0d9b84712dfd43fd9906854f239 100644 --- a/data-services/src/main/java/org/pdxfinder/services/PublicationService.java +++ b/data-services/src/main/java/org/pdxfinder/services/PublicationService.java @@ -5,7 +5,9 @@ import org.pdxfinder.services.dto.europepmc.Publication; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; @Service public class PublicationService { @@ -24,7 +26,7 @@ public class PublicationService { pubMedIds = sanitizePubMedIds(pubMedIds); List<Publication> publications = new ArrayList<>(); pubMedIds.forEach(pubMedId->{ - String api = String.format("%s?query=%s&resultType=core&format=json", DataUrl.EUROPE_PMC_URL.get(), pubMedId); + String api = String.format("%s?query=ext_id:%s&resultType=core&format=json", DataUrl.EUROPE_PMC_URL.get(), pubMedId); publications.add(restTemplate.getForObject(api, Publication.class)); }); @@ -36,6 +38,7 @@ public class PublicationService { public List<String> sanitizePubMedIds(List<String> pubMedIds){ List<String> cleanedPubMedIds = new ArrayList<>(); pubMedIds.forEach(pubMedId -> { + pubMedId = pubMedId.toUpperCase(); pubMedId = pubMedId.replace(PUBLICATION_PREFIX, EMPTY_STRING); pubMedId = pubMedId.replaceAll("\\s+",EMPTY_STRING); if (pubMedId.contains(";")){ diff --git a/data-services/src/main/java/org/pdxfinder/services/SearchService.java b/data-services/src/main/java/org/pdxfinder/services/SearchService.java index 1a9f6623f767412c1c099549dafd5ec6c91a1430..85a690f3db6111f0b50fada0c7e8e72b19db6e03 100644 --- a/data-services/src/main/java/org/pdxfinder/services/SearchService.java +++ b/data-services/src/main/java/org/pdxfinder/services/SearchService.java @@ -45,7 +45,7 @@ public class SearchService { List<String> sampleTumorTypeOptions = new ArrayList<>(); List<String> dataAvailableOptions = new ArrayList<>(); - private static List<String> modelsIDsForAutoSuggest; + public SearchService(ModelCreationRepository modelCreationRepository, @@ -64,8 +64,6 @@ public class SearchService { this.drugService = drugService; this.searchDS = searchDS; - - facets.put("datasource_options", datasourceOptions); facets.put("patient_age_options", patientAgeOptions); facets.put("patient_gender_options", patientGenderOptions); @@ -73,11 +71,6 @@ public class SearchService { facets.put("data_available_options", dataAvailableOptions); facets.put("sample_tumor_type_options", sampleTumorTypeOptions); - - Set<ModelForQuery> modelsForAutoSuggest = searchDS.search(getFacetMap(Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(), Optional.empty(),Optional.empty(),Optional.empty(), Optional.empty(),Optional.empty(),Optional.empty(), Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(),Optional.empty(), Optional.empty())); - - modelsIDsForAutoSuggest = modelsForAutoSuggest.stream().map(ModelForQuery::getExternalId).collect(Collectors.toList()); - } @@ -103,6 +96,7 @@ public class SearchService { Optional<List<String>> copy_number_alteration, Optional<List<String>> gene_expression, Optional<List<String>> cytogenetics, + Optional<List<String>> model_id, Integer page, Integer size){ @@ -126,7 +120,8 @@ public class SearchService { access_modalities, copy_number_alteration, gene_expression, - cytogenetics + cytogenetics, + model_id ); WebSearchDTO wsDTO = new WebSearchDTO(); @@ -177,8 +172,7 @@ public class SearchService { wsDTO.setTextSearchDescription(textSearchDescription); wsDTO.setTotalResults(searchDS.getModels().size()); - wsDTO.setMainSearchFieldOptions(autoCompleteService.getAutoSuggestions(modelsIDsForAutoSuggest)); - + wsDTO.setMainSearchFieldOptions(autoCompleteService.getAutoSuggestions()); List<ModelForQuery> resultSet = new ArrayList<>(results).subList((page - 1) * size, Math.min(((page - 1) * size) + size, results.size())); wsDTO.setResults(resultSet); @@ -210,7 +204,8 @@ public class SearchService { Optional<List<String>> access_modalities, Optional<List<String>> copy_number_alteration, Optional<List<String>> gene_expression, - Optional<List<String>> cytogenetics){ + Optional<List<String>> cytogenetics, + Optional<List<String>> model_id){ Map<SearchFacetName, List<String>> configuredFacets = getFacetMap( query, @@ -231,7 +226,8 @@ public class SearchService { access_modalities, copy_number_alteration, gene_expression, - cytogenetics + cytogenetics, + model_id ); @@ -244,7 +240,7 @@ public class SearchService { - public Map<SearchFacetName, List<String>> getFacetMap( + private Map<SearchFacetName, List<String>> getFacetMap( Optional<String> query, Optional<List<String>> datasource, Optional<List<String>> diagnosis, @@ -263,8 +259,8 @@ public class SearchService { Optional<List<String>> access_modalities, Optional<List<String>> copy_number_alteration, Optional<List<String>> gene_expression, - Optional<List<String>> cytogenetics - + Optional<List<String>> cytogenetics, + Optional<List<String>> model_id ) { @@ -402,6 +398,13 @@ public class SearchService { } } + if (model_id.isPresent() && !model_id.get().isEmpty()) { + configuredFacets.put(SearchFacetName.model_id, new ArrayList<>()); + for (String s : model_id.get()) { + configuredFacets.get(SearchFacetName.model_id).add(s); + } + } + return configuredFacets; } diff --git a/data-services/src/main/java/org/pdxfinder/services/Statistics.java b/data-services/src/main/java/org/pdxfinder/services/Statistics.java index 9c5f58f9cbf518422c040c2cae3d5c32be61b90d..c67d3df946a57be911b0540d4f565f363c9e463e 100644 --- a/data-services/src/main/java/org/pdxfinder/services/Statistics.java +++ b/data-services/src/main/java/org/pdxfinder/services/Statistics.java @@ -131,10 +131,12 @@ public class Statistics { // Populate the chartData category List categories.add(StatisticsDTO.getCategory()); - - StatisticsDTO.getDataCounts().forEach(CountDTO -> { - dataMap.get(CountDTO.getKey()).add(CountDTO.getValue()); - }); + if(StatisticsDTO.getDataCounts()!= null){ + StatisticsDTO.getDataCounts().forEach(CountDTO -> { + if(CountDTO != null && CountDTO.getKey() != null && dataMap.containsKey(CountDTO.getKey())) + dataMap.get(CountDTO.getKey()).add(CountDTO.getValue()); + }); + } }); diff --git a/data-services/src/main/java/org/pdxfinder/services/TransformerService.java b/data-services/src/main/java/org/pdxfinder/services/TransformerService.java index f93696d4fbdfa9ccf0665a2c3278a323f284d0cb..0473b49b2adec84264b3b762b0f8de8f03173f1c 100644 --- a/data-services/src/main/java/org/pdxfinder/services/TransformerService.java +++ b/data-services/src/main/java/org/pdxfinder/services/TransformerService.java @@ -2,16 +2,9 @@ package org.pdxfinder.services; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.pdxfinder.rdbms.dao.PdmrPdxInfo; -import org.pdxfinder.rdbms.dao.Sample; -import org.pdxfinder.rdbms.dao.Treatment; -import org.pdxfinder.rdbms.dao.Validation; -import org.pdxfinder.rdbms.repositories.TransPdxInfoRepository; -import org.pdxfinder.rdbms.repositories.TransSampleRepository; -import org.pdxfinder.rdbms.repositories.TransTreatmentRepository; -import org.pdxfinder.rdbms.repositories.TransValidationRepository; -import org.pdxfinder.services.constants.OmicCSVColumn; -import org.pdxfinder.services.constants.PdmrOmicCol; +import org.pdxfinder.rdbms.dao.*; +import org.pdxfinder.rdbms.repositories.*; +import org.pdxfinder.services.constants.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -514,19 +507,19 @@ public class TransformerService { for (Treatment treatment: treatments){ treatment.setPdmrPdxInfo(pdmrPdxInfo); } - transTreatmentRepository.save(treatments); + transTreatmentRepository.saveAll(treatments); // Update the Foreign Key pdxinfo_id for the corresponding validations for (Validation validation : validations){ validation.setPdmrPdxInfo(pdmrPdxInfo); } - transValidationRepository.save(validations); + transValidationRepository.saveAll(validations); // Update the Foreign key pdxinfo_id for the corresponding samples for (Sample sample : sampleList){ sample.setPdmrPdxInfo(pdmrPdxInfo); } - transSampleRepository.save(sampleList); + transSampleRepository.saveAll(sampleList); log.info("Loaded Record for Patient" + specimenSearch.get("PATIENTID")); diff --git a/data-services/src/main/java/org/pdxfinder/services/UtilityService.java b/data-services/src/main/java/org/pdxfinder/services/UtilityService.java index 5e28ead7f0eb9e27ceec7073677b7e8a36996e93..f3f09c341878c4ebd92ba0d2ecd8850724bd851d 100644 --- a/data-services/src/main/java/org/pdxfinder/services/UtilityService.java +++ b/data-services/src/main/java/org/pdxfinder/services/UtilityService.java @@ -2,22 +2,20 @@ package org.pdxfinder.services; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.MappingIterator; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.csv.CsvMapper; import com.fasterxml.jackson.dataformat.csv.CsvSchema; -import org.apache.poi.hssf.usermodel.HSSFCell; -import org.apache.poi.hssf.usermodel.HSSFRow; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.HttpURLConnection; @@ -30,10 +28,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.springframework.util.StringUtils; -import org.springframework.web.multipart.MultipartFile; - /* * Created by abayomi on 12/02/2019. */ @@ -50,7 +44,30 @@ public class UtilityService { private static final String COMMA_DELIMITER = ","; private static final String NEW_LINE_SEPARATOR = "\n"; + /************************************************************************************************************* + * DATA SERIALIZER METHODS SECTION * + ************************************************************************************************************/ + + public List<Map<String, String>> serializeDataToMaps(String fileName) { + + + String fileExtension = getFileExtension(fileName); + + List<Map<String, String>> csvMaps; + + if (fileExtension.equals("csv")) { + + csvMaps = serializeCSVToMaps(fileName); + }else if (fileExtension.equals("json")) { + + csvMaps = (List) serializeJSONToMaps(fileName); + } else { + + csvMaps = serializeExcelDataNoIterator(fileName,0,1); + } + return csvMaps; + } public String serializeToCsvWithIncludeNonEmpty(List<?> pojoList) throws IOException { @@ -79,33 +96,6 @@ public class UtilityService { return csvMapper.writer(schema).writeValueAsString(csvData); } - /************************************************************************************************************* - * DATA SERIALIZER METHODS SECTION * - ************************************************************************************************************/ - - public List<Map<String, String>> serializeDataToMaps(String fileName) { - - - String fileExtension = getFileExtension(fileName); - - List<Map<String, String>> csvMaps; - - if (fileExtension.equals("csv")) { - - csvMaps = serializeCSVToMaps(fileName); - }else if (fileExtension.equals("json")) { - - csvMaps = (List) serializeJSONToMaps(fileName); - } else { - - csvMaps = serializeExcelDataNoIterator(fileName,0,1); - } - - return csvMaps; - } - - - public Map<String, List<Map<String, String>> > serializeAndGroupFileContent(String fileName, String groupColumn) { String fileExtension = getFileExtension(fileName); @@ -163,73 +153,17 @@ public class UtilityService { return groupedMap; } - - - - - - - - - - /************************************************************************************************************* * MICROSOFT EXCEL FILE HANDLER SECTION * ************************************************************************************************************/ - - - // EXCEL FILE READER : READ EXCEL FILE USING ITERATOR, NOT VERY SAFE FOR EMPTY/FORMATTED CELLS - public List<Map<String, String>> serializeExcelData(String excelURL) { - - FileInputStream inputStream = convertFileToStream(excelURL); - - int dataRow = 0; - List<String> tableHead = new ArrayList<>(); - List<Map<String, String>> csvMap = new ArrayList<>(); - - try(Workbook workbook = WorkbookFactory.create(inputStream)) { - Row row; - Sheet spreadsheet = workbook.getSheetAt(0); - Iterator<Row> rowIterator = spreadsheet.iterator(); - - while (rowIterator.hasNext()) // Read the rows - { - row = rowIterator.next(); - Iterator<Cell> cellIterator = row.cellIterator(); - - if (dataRow == 0) { - tableHead = getXlsTableHeadData(cellIterator); - - } else { - Map<String, String> rowMap = getXlsCellData(cellIterator, tableHead); - csvMap.add(rowMap); - } - dataRow++; - } - - inputStream.close(); - } catch (IOException | InvalidFormatException ex) { - log.warn(ex.getMessage()); - } - - return csvMap; - } - - - - // EXCEL FILE READER : READ EXCEL FILE WITHOUT USING ITERATOR, SAFER LOADING FOR EMPTY CELLS public List<Map<String, String>> serializeExcelDataNoIterator(String excelURL, int sheet, int startRow) { - FileInputStream inputStream = convertFileToStream(excelURL); - return serializeExcelDataNoIterator(inputStream, sheet, startRow); - } public List<Map<String, String>> serializeExcelDataNoIterator(InputStream inputStream, int sheet, int startRow) { - List<String> tableHead = new ArrayList<>(); List<Map<String, String>> csvMap = new ArrayList<>(); @@ -299,11 +233,6 @@ public class UtilityService { return csvMap; } - - - - - // EXCEL WRITER : CREATE .XLSX FILE public void writeXLSXFile(List<Map<String, String>> dataList,String fileName, String sheetName) { String excelFileName = homeDir+"/Downloads/"+fileName; @@ -356,70 +285,6 @@ public class UtilityService { } - - - // EXCEL WRITER : CREATE .XLS FILE - public void writeXLSFile() throws IOException { - - String excelFileName = "";//name of excel file - - String sheetName = "Sheet1";//name of sheet - - try (HSSFWorkbook wb = new HSSFWorkbook()) { - HSSFSheet sheet = wb.createSheet(sheetName); - - //iterating r number of rows - for (int r = 0; r < 5; r++) { - HSSFRow row = sheet.createRow(r); - - //iterating c number of columns - for (int c = 0; c < 5; c++) { - HSSFCell cell = row.createCell(c); - - cell.setCellValue("Cell " + r + " " + c); - } - } - - FileOutputStream fileOut = new FileOutputStream(excelFileName); - - //write this workbook to an Outputstream. - wb.write(fileOut); - fileOut.flush(); - fileOut.close(); - } - } - - - - // GET SMALL SECTIONS OF EXCEL: RETRIEVE FIRST ROW OF EXCEL SHEET - public List<String> getXlsHead(String excelURL, int sheet) { - - FileInputStream inputStream = convertFileToStream(excelURL); - - List<String> tableHead = new ArrayList<>(); - - try(Workbook workbook = WorkbookFactory.create(inputStream)) { - Row row; - Sheet spreadsheet = workbook.getSheetAt(sheet); - Iterator<Row> rowIterator = spreadsheet.iterator(); - - while (rowIterator.hasNext()) - { - row = rowIterator.next(); - - Iterator<Cell> cellIterator = row.cellIterator(); - tableHead = getXlsTableHeadData(cellIterator); - break; - } - - }catch (Exception e){ - log.warn(e.getMessage()); - } - - return tableHead; - } - - // GET SMALL SECTIONS OF EXCEL: RETRIEVE FIRST ROW OF EXCEL SHEET public List<String> getXlsTableHeadData(Iterator<Cell> cellIterator){ @@ -437,31 +302,6 @@ public class UtilityService { return data; } - - - - // GET SMALL SECTIONS OF EXCEL: RETRIEVE BODY ROWS OF EXCEL SHEET - private Map<String, String> getXlsCellData(Iterator<Cell> cellIterator, List<String> tableHead){ - - Map<String, String> rowMap = new HashMap(); - - int column = 0; - while (cellIterator.hasNext()) - { - Cell cell = cellIterator.next(); - - if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC){ - rowMap.put(tableHead.get(column).trim(), cell.getNumericCellValue() + ""); - }else { - rowMap.put(tableHead.get(column).trim(), cell.getStringCellValue() + ""); - } - column++; - } - return rowMap; - } - - - // EXCEL CUSTOMIZER : SET EXCEL CELL FONT SIZE AND COLOR private CellStyle setXLSFont(Workbook wb, int fontSize, IndexedColors colors){ @@ -478,49 +318,34 @@ public class UtilityService { return headerCellStyle; } - - - - - - - - - - - - - - /************************************************************************************************************* * CSV FILE HANDLER SECTION * ************************************************************************************************************/ public List<Map<String, String>> serializeMultipartFile(MultipartFile multipartFile) { - - String[] stringArr = multipartFile.getOriginalFilename().split("\\."); - String type = stringArr[stringArr.length - 1]; - - // multipartFile.getContentType() - - InputStream inputStream = null; List<Map<String, String>> dataList = new ArrayList<>(); + if(multipartFile.getOriginalFilename() != null) { - try { - inputStream = multipartFile.getInputStream(); - } catch (IOException e) { - log.warn(e.getMessage()); - } + InputStream inputStream = null; + String type = ""; + try { + String[] stringArr = multipartFile.getOriginalFilename().split("\\."); + type = stringArr[stringArr.length - 1]; - if (type.equals("xlsx")) { + inputStream = multipartFile.getInputStream(); + } catch (Exception e) { + log.warn(e.getMessage()); + } + if (type.equals("xlsx")) { - dataList = serializeExcelDataNoIterator(inputStream, 0, 1); + dataList = serializeExcelDataNoIterator(inputStream, 0, 1); - } else if (type.equals("csv")) { + } else if (type.equals("csv")) { - assert inputStream != null; - DataInputStream csvData = new DataInputStream(inputStream); - dataList = serializeCSVToMaps(csvData); + assert inputStream != null; + DataInputStream csvData = new DataInputStream(inputStream); + dataList = serializeCSVToMaps(csvData); + } } return dataList; @@ -709,14 +534,6 @@ public class UtilityService { // write to csv at the specified destination writeCsvFile(stringMapList, destination); } - - - - - - - - /************************************************************************************************************* * JSON FILE HANDLER SECTION * ************************************************************************************************************/ diff --git a/data-services/src/main/java/org/pdxfinder/services/constants/DataProvider.java b/data-services/src/main/java/org/pdxfinder/services/constants/DataProvider.java index 47c48a758b0610e85772df331f084481f0c6c2be..81969fbb4ce806b5e036b8efe48acc8012a15412 100644 --- a/data-services/src/main/java/org/pdxfinder/services/constants/DataProvider.java +++ b/data-services/src/main/java/org/pdxfinder/services/constants/DataProvider.java @@ -3,13 +3,13 @@ package org.pdxfinder.services.constants; public enum DataProvider { Test_Minimal("Test-Minimal"), - PDXNet_HCI_BCM("PDXNet-HCI-BCM"), + HCI_BCM("HCI-BCM"), IRCC_CRC("IRCC-CRC"), JAX("JAX"), - PDXNet_MDAnderson("PDXNet-MDAnderson"), + MDAnderson("MDAnderson"), PDMR("PDMR"), - PDXNet_Wistar_MDAnderson_Penn("PDXNet-Wistar-MDAnderson-Penn"), - PDXNet_WUSTL("PDXNet-WUSTL"), + Wistar_MDAnderson_Penn("Wistar-MDAnderson-Penn"), + WUSTL("WUSTL"), CRL("CRL"), Curie_BC("Curie-BC"), Curie_LC("Curie-LC"), @@ -23,12 +23,13 @@ public enum DataProvider { VHIO_CRC("VHIO-CRC"), DFCI_CPDM("DFCI-CPDM"), NKI("NKI"), - PIPELINE("PIPELINE"), JAX_XDOG("JAX-XDOG"), SJCRH("SJCRH"), UMCG("UMCG"), VHIO_PC("VHIO-PC"), - LIH("LIH"); + LIH("LIH"), + PPTC("PPTC"), + PIPELINE("PIPELINE"); private String name; DataProvider(String name) { @@ -40,3 +41,4 @@ public enum DataProvider { return name; } } + diff --git a/data-services/src/main/java/org/pdxfinder/services/constants/DataProviderGroup.java b/data-services/src/main/java/org/pdxfinder/services/constants/DataProviderGroup.java index 599c609d36679f2cf7a588966bf14f28c4a79b9c..a36de1cac1775c49a0e45e5aa18696c100bf0891 100644 --- a/data-services/src/main/java/org/pdxfinder/services/constants/DataProviderGroup.java +++ b/data-services/src/main/java/org/pdxfinder/services/constants/DataProviderGroup.java @@ -1,12 +1,14 @@ package org.pdxfinder.services.constants; import java.util.Arrays; +import java.util.Collections; import java.util.EnumMap; import java.util.List; public enum DataProviderGroup { All, EurOPDX, + PDXNet, UPDOG, CustomLoaders; @@ -15,14 +17,6 @@ public enum DataProviderGroup { EnumMap<DataProviderGroup, List<DataProvider>> map = new EnumMap<>(DataProviderGroup.class); map.put(DataProviderGroup.All, Arrays.asList(DataProvider.values())); - - // DS: temp - /* - map.put(DataProviderGroup.EurOPDX, Arrays.asList( - DataProvider.Curie_LC - )); - */ - map.put(DataProviderGroup.EurOPDX, Arrays.asList( DataProvider.Curie_BC, DataProvider.Curie_LC, @@ -35,13 +29,12 @@ public enum DataProviderGroup { DataProvider.VHIO_BC, DataProvider.VHIO_CRC, DataProvider.NKI, - DataProvider.PIPELINE, DataProvider.UMCG, DataProvider.VHIO_PC, - DataProvider.LIH + DataProvider.LIH, + DataProvider.PPTC )); - map.put(DataProviderGroup.UPDOG, Arrays.asList( DataProvider.IRCC_GC, DataProvider.IRCC_CRC, @@ -63,15 +56,23 @@ public enum DataProviderGroup { DataProvider.SJCRH, DataProvider.UMCG, DataProvider.VHIO_PC, - DataProvider.LIH + DataProvider.LIH, + DataProvider.PPTC, + DataProvider.WUSTL, + DataProvider.MDAnderson, + DataProvider.Wistar_MDAnderson_Penn, + DataProvider.HCI_BCM + )); + + map.put(DataProviderGroup.PDXNet, Arrays.asList( + DataProvider.WUSTL, + DataProvider.MDAnderson, + DataProvider.Wistar_MDAnderson_Penn, + DataProvider.HCI_BCM )); - map.put(DataProviderGroup.CustomLoaders, Arrays.asList( - DataProvider.JAX, - DataProvider.PDXNet_MDAnderson, - DataProvider.PDXNet_HCI_BCM, - DataProvider.PDXNet_Wistar_MDAnderson_Penn, - DataProvider.PDXNet_WUSTL + map.put(DataProviderGroup.CustomLoaders, Collections.singletonList( + DataProvider.JAX )); return map.get(group); diff --git a/data-services/src/main/java/org/pdxfinder/services/constants/DataUrl.java b/data-services/src/main/java/org/pdxfinder/services/constants/DataUrl.java index 338dd892eec20a6ba9a5d766b1df9814cd158f89..f464cf145163531f314778bea875a4cf0f9b7e5e 100644 --- a/data-services/src/main/java/org/pdxfinder/services/constants/DataUrl.java +++ b/data-services/src/main/java/org/pdxfinder/services/constants/DataUrl.java @@ -16,7 +16,7 @@ public enum DataUrl { private String value; - private DataUrl(String val) { + DataUrl(String val) { value = val; } diff --git a/data-services/src/main/java/org/pdxfinder/services/constants/OmicCSVColumn.java b/data-services/src/main/java/org/pdxfinder/services/constants/OmicCSVColumn.java index f9b2c6fd52530a6e675e6451fe99f11cc13b962b..5045c0f18145c94cbf374909eb5aca5f0d1a88dc 100644 --- a/data-services/src/main/java/org/pdxfinder/services/constants/OmicCSVColumn.java +++ b/data-services/src/main/java/org/pdxfinder/services/constants/OmicCSVColumn.java @@ -32,7 +32,7 @@ public enum OmicCSVColumn { private String value; - private OmicCSVColumn(String val) { + OmicCSVColumn(String val) { value = val; } diff --git a/data-services/src/main/java/org/pdxfinder/services/ds/Harmonizer.java b/data-services/src/main/java/org/pdxfinder/services/ds/Harmonizer.java index 90e813dff5c13801dad763e6142fb7988d5c0d45..9d809e92432bf73082f4ce92dab30289450a8a4f 100644 --- a/data-services/src/main/java/org/pdxfinder/services/ds/Harmonizer.java +++ b/data-services/src/main/java/org/pdxfinder/services/ds/Harmonizer.java @@ -1,18 +1,9 @@ package org.pdxfinder.services.ds; -import org.apache.commons.lang3.StringUtils; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.graph.dao.QualityAssurance; +import com.github.openjson.*; import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; import org.springframework.beans.factory.annotation.Autowired; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - public class Harmonizer { diff --git a/data-services/src/main/java/org/pdxfinder/services/ds/SearchDS.java b/data-services/src/main/java/org/pdxfinder/services/ds/SearchDS.java index a87d9eec7792e494a31ed6977f1bf77bf2498c13..ac88ec6156cdfb6a724dc7d23058c89f428a1d7f 100644 --- a/data-services/src/main/java/org/pdxfinder/services/ds/SearchDS.java +++ b/data-services/src/main/java/org/pdxfinder/services/ds/SearchDS.java @@ -2,13 +2,9 @@ package org.pdxfinder.services.ds; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONException; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.DataProjection; import org.pdxfinder.graph.repositories.DataProjectionRepository; -import org.pdxfinder.services.search.WebFacetSection; -import org.pdxfinder.services.search.WebFacetContainer; import org.pdxfinder.services.search.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,12 +12,10 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import org.springframework.util.Assert; -import java.lang.reflect.Array; import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; - import static java.lang.Long.parseLong; @@ -251,6 +245,9 @@ public class SearchDS { pdxModelSection.addComponent(datasource); facetOptionMap.put("datasource", datasourceOptions); + OneParamTextFilter modelId = new OneParamTextFilter("MODEL ID", "model_id", false, + FilterType.OneParamTextFilter.get(), "MODEL", getUniqueModelIds(), new ArrayList<>()); + pdxModelSection.addComponent(modelId); //project filter def Set<String> projectsSet = new HashSet<>(); @@ -614,21 +611,8 @@ public class SearchDS { switch(facet){ case query: - - /* - Set<ModelForQuery> result_2 = oneParamCheckboxSearch.searchOnCollection_model(filters.get(SearchFacetName.query), result); - if (result_2.size() == 0) { - result = oneParamCheckboxSearch.searchOnCollection(facetOptionMap.get("query"), filters.get(SearchFacetName.query), result, ModelForQuery::getAllOntologyTermAncestors); - } else { - result = result_2; - } - */ - - Set<ModelForQuery> result_2 = oneParamCheckboxSearch.searchOnCollection_model(filters.get(SearchFacetName.query), result); + //List<String> searchParams, Set<ModelForQuery> mfqSet, Function<ModelForQuery, List<String>> searchFunc result = oneParamCheckboxSearch.searchOnCollection(facetOptionMap.get("query"), filters.get(SearchFacetName.query), result, ModelForQuery::getAllOntologyTermAncestors); - - result.addAll(result_2); - break; //We don't need to provide a replacement string list for datasource, since it is already using the datasource abbrev as key! @@ -727,6 +711,9 @@ public class SearchDS { result = cytogeneticsSearch.search(filters.get(SearchFacetName.cytogenetics), result, ModelForQuery::addCytogenetics); break; + case model_id: + result = oneParamCheckboxSearch.searchOnString(null, filters.get(SearchFacetName.model_id), result, ModelForQuery::getExternalId); + default: //undexpected filter option log.warn("Unrecognised facet {} passed to search, skipping", facet.getName()); @@ -760,8 +747,15 @@ public class SearchDS { this.models = models; } + public List<String> getModelIds(){ + return models.stream().distinct().map(s->s.getExternalId()).collect(Collectors.toList()); + } + public List<String> getUniqueModelIds(){ + + return getModelIds().stream().distinct().collect(Collectors.toList()); + } /** * This method loads the ModelForQuery Data Projection object and initializes the models @@ -1271,4 +1265,4 @@ public class SearchDS { } -} +} \ No newline at end of file diff --git a/data-services/src/main/java/org/pdxfinder/services/ds/SearchFacetName.java b/data-services/src/main/java/org/pdxfinder/services/ds/SearchFacetName.java index 29125cac267165bd0728e207dc8391bb9deb820d..74844b1b59119d5b01499c49a51641cf9ba51164 100644 --- a/data-services/src/main/java/org/pdxfinder/services/ds/SearchFacetName.java +++ b/data-services/src/main/java/org/pdxfinder/services/ds/SearchFacetName.java @@ -25,7 +25,8 @@ public enum SearchFacetName { copy_number_alteration, patient_treatment, gene_expression, - cytogenetics; + cytogenetics, + model_id; public String getName() { return name(); diff --git a/data-services/src/main/java/org/pdxfinder/services/ds/Standardizer.java b/data-services/src/main/java/org/pdxfinder/services/ds/Standardizer.java index 61bbd5269d02cd7edaaf034f18f9e97df39bc7c9..70bf753f6d0e4fba0fb1f3dbfec89d52a898b749 100644 --- a/data-services/src/main/java/org/pdxfinder/services/ds/Standardizer.java +++ b/data-services/src/main/java/org/pdxfinder/services/ds/Standardizer.java @@ -1,20 +1,9 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package org.pdxfinder.services.ds; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.graph.dao.Drug; -import org.pdxfinder.graph.dao.Response; -import org.pdxfinder.graph.dao.TreatmentComponent; -import org.pdxfinder.graph.dao.TreatmentProtocol; + +import com.github.openjson.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.security.spec.ECField; -import java.util.ArrayList; - /** * * @author sbn diff --git a/data-services/src/main/java/org/pdxfinder/services/dto/LoaderDTO.java b/data-services/src/main/java/org/pdxfinder/services/dto/LoaderDTO.java index 4af5ab5e832fb421ab0aea576de9164b736fb60b..dcb293ccced38584a1997d9ec081c5335df86dad 100644 --- a/data-services/src/main/java/org/pdxfinder/services/dto/LoaderDTO.java +++ b/data-services/src/main/java/org/pdxfinder/services/dto/LoaderDTO.java @@ -1,6 +1,6 @@ package org.pdxfinder.services.dto; -import org.neo4j.ogm.json.JSONArray; +import com.github.openjson.JSONArray; import org.pdxfinder.graph.dao.*; import java.util.HashMap; diff --git a/data-services/src/main/java/org/pdxfinder/services/dto/europepmc/Publication.java b/data-services/src/main/java/org/pdxfinder/services/dto/europepmc/Publication.java index ec724d73a57860d8cce2553cb8fcff87efc501fb..16d8928b288409e8da8f97aec74d7c18707436b3 100644 --- a/data-services/src/main/java/org/pdxfinder/services/dto/europepmc/Publication.java +++ b/data-services/src/main/java/org/pdxfinder/services/dto/europepmc/Publication.java @@ -2,7 +2,9 @@ package org.pdxfinder.services.dto.europepmc; import com.fasterxml.jackson.annotation.JsonInclude; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @JsonInclude(JsonInclude.Include.NON_NULL) public class Publication { diff --git a/data-services/src/main/java/org/pdxfinder/services/dto/pdxgun/Reference.java b/data-services/src/main/java/org/pdxfinder/services/dto/pdxgun/Reference.java index 784b3cd7305570251561f95d3ff7d9946611a502..dc22f2bb8a120325e8eb18d6c8cc1804ce8de5f0 100644 --- a/data-services/src/main/java/org/pdxfinder/services/dto/pdxgun/Reference.java +++ b/data-services/src/main/java/org/pdxfinder/services/dto/pdxgun/Reference.java @@ -1,7 +1,5 @@ package org.pdxfinder.services.dto.pdxgun; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Map; public class Reference { diff --git a/data-services/src/main/java/org/pdxfinder/services/graphqlclient/Operator.java b/data-services/src/main/java/org/pdxfinder/services/graphqlclient/Operator.java index 04726731a0ef2494c8ba2f65c154f1312ab5ec1d..3ecbb76eede378a79e9fd5323d504b0a9c2d7b6f 100644 --- a/data-services/src/main/java/org/pdxfinder/services/graphqlclient/Operator.java +++ b/data-services/src/main/java/org/pdxfinder/services/graphqlclient/Operator.java @@ -6,7 +6,7 @@ public enum Operator { IN("_in:"); private String value; - private Operator(String val) { + Operator(String val) { value = val; } public String get() { diff --git a/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadMarkers.java b/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadMarkers.java index 9e0acaf180e402f38f8b7b132330d036e0374cef..84620f4f37f2079ccf51fed6211cd6a277405e5d 100644 --- a/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadMarkers.java +++ b/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadMarkers.java @@ -7,11 +7,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; -import java.time.*; -import java.util.*; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; @Service public class LoadMarkers { @@ -27,7 +32,7 @@ public class LoadMarkers { public void loadGenes(String dataURL) { Instant start = Instant.now(); - log.info("Downloading latest marker data from {}...", dataURL); + log.info("Downloading latest marker data from {}...", dataURL.substring(0, 50)); BufferedReader reader = downloadDataFromURL(dataURL); List<Marker> markers = parseMarkers(reader); dataImportService.saveAllMarkers(markers); diff --git a/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadNCIT.java b/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadNCIT.java index 52870761d20419e82cef1438fd42cb2d2167aef9..f661d799a19bd63bc65dd1c7d823f74f90feb46a 100644 --- a/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadNCIT.java +++ b/data-services/src/main/java/org/pdxfinder/services/loader/envload/LoadNCIT.java @@ -1,7 +1,6 @@ package org.pdxfinder.services.loader.envload; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.OntologyTerm; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.UtilityService; @@ -10,16 +9,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.net.URLEncoder; -import java.time.Duration; -import java.time.Instant; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.time.*; +import java.util.*; @Service public class LoadNCIT { diff --git a/data-services/src/main/java/org/pdxfinder/services/ontology/Ontolia.java b/data-services/src/main/java/org/pdxfinder/services/ontology/Ontolia.java index 878e4d2742cec7f8c3035bcca9789815469da68f..6b5ba9fd88b61e3c1514ad0f88e1c2112bd3097b 100644 --- a/data-services/src/main/java/org/pdxfinder/services/ontology/Ontolia.java +++ b/data-services/src/main/java/org/pdxfinder/services/ontology/Ontolia.java @@ -1,7 +1,6 @@ package org.pdxfinder.services.ontology; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.OntologyTerm; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.UtilityService; diff --git a/data-services/src/main/java/org/pdxfinder/services/pdf/Label.java b/data-services/src/main/java/org/pdxfinder/services/pdf/Label.java index 36ef7d1045ef4948f8f1c7074bd10684c5436b7f..49672b0b83d22638ea58d710d34f37aa36b09032 100755 --- a/data-services/src/main/java/org/pdxfinder/services/pdf/Label.java +++ b/data-services/src/main/java/org/pdxfinder/services/pdf/Label.java @@ -81,7 +81,7 @@ public enum Label { private String value; - private Label(String val) { + Label(String val) { value = val; } diff --git a/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxSearch.java b/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxSearch.java index 59a9b9f4afa333b059735aa8835f1ca438449bd9..03ea63a70ab63ecedfe6adeb79cb36a0412e6ebe 100644 --- a/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxSearch.java +++ b/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxSearch.java @@ -58,28 +58,6 @@ public class OneParamCheckboxSearch extends GeneralSearch{ } - public Set<ModelForQuery> searchOnCollection_model(List<String> searchParams, Set<ModelForQuery> mfqSet){ - - Set<ModelForQuery> results = new HashSet<>(); - - List<String> queryItems = Arrays.asList(searchParams.get(0).split(",")); - - for(ModelForQuery mfq: mfqSet) { - - if (queryItems.contains(mfq.getExternalId())) { - results.add(mfq); - } - - /* - if (mfq.getExternalId().equals(searchParams.get(0))) { - results.add(mfq); - } - */ - } - return results; - } - - /** * Performs a search on a selected ModelForQuery field that's type is List of Strings @@ -93,8 +71,7 @@ public class OneParamCheckboxSearch extends GeneralSearch{ List<String> decodedSearchParams = new ArrayList<>(); if(replacementStrings == null){ - // decodedSearchParams = searchParams; - decodedSearchParams = Arrays.asList(searchParams.get(0).split(",")); + decodedSearchParams = searchParams; } else{ diff --git a/data-services/src/test/java/org/pdxfinder/DataImportServiceTests.java b/data-services/src/test/java/org/pdxfinder/DataImportServiceTests.java index fd59244e40f02cefa441fc4d303540e517879a8d..195567d69d7a28ad38120789e5ce9b1d92b2718e 100644 --- a/data-services/src/test/java/org/pdxfinder/DataImportServiceTests.java +++ b/data-services/src/test/java/org/pdxfinder/DataImportServiceTests.java @@ -1,5 +1,6 @@ package org.pdxfinder; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import org.junit.Assert; @@ -8,11 +9,11 @@ import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import org.pdxfinder.graph.dao.DataProjection; import org.pdxfinder.graph.dao.Group; import org.pdxfinder.graph.dao.Patient; import org.pdxfinder.graph.dao.PatientSnapshot; -import org.pdxfinder.graph.repositories.PatientRepository; -import org.pdxfinder.graph.repositories.PatientSnapshotRepository; +import org.pdxfinder.graph.repositories.*; import org.pdxfinder.services.DataImportService; import org.springframework.beans.factory.annotation.Autowired; @@ -20,11 +21,31 @@ import java.util.HashSet; public class DataImportServiceTests extends BaseTest { - @Mock - private PatientSnapshotRepository patientSnapshotRepository; - - @Mock - private PatientRepository patientRepository; + @Mock private TumorTypeRepository tumorTypeRepository; + @Mock private HostStrainRepository hostStrainRepository; + @Mock private EngraftmentTypeRepository engraftmentTypeRepository; + @Mock private EngraftmentSiteRepository engraftmentSiteRepository; + @Mock private EngraftmentMaterialRepository engraftmentMaterialRepository; + @Mock private GroupRepository groupRepository; + @Mock private PatientRepository patientRepository; + @Mock private ModelCreationRepository modelCreationRepository; + @Mock private TissueRepository tissueRepository; + @Mock private PatientSnapshotRepository patientSnapshotRepository; + @Mock private SampleRepository sampleRepository; + @Mock private MarkerRepository markerRepository; + @Mock private MarkerAssociationRepository markerAssociationRepository; + @Mock private MolecularCharacterizationRepository molecularCharacterizationRepository; + @Mock private QualityAssuranceRepository qualityAssuranceRepository; + @Mock private OntologyTermRepository ontologyTermRepository; + @Mock private SpecimenRepository specimenRepository; + @Mock private PlatformRepository platformRepository; + @Mock private PlatformAssociationRepository platformAssociationRepository; + @Mock private DataProjectionRepository dataProjectionRepository; + @Mock private TreatmentSummaryRepository treatmentSummaryRepository; + @Mock private TreatmentProtocolRepository treatmentProtocolRepository; + @Mock private CurrentTreatmentRepository currentTreatmentRepository; + @Mock private ExternalUrlRepository externalUrlRepository; + @Mock private TreatmentRepository treatmentRepository; @Spy @InjectMocks @@ -109,22 +130,6 @@ public class DataImportServiceTests extends BaseTest { Assert.assertEquals(ELAPSED_TIME, actualSnapshot.getDateAtCollection()); } - @Test - public void Given_GetPatientSnapshot6Param_When_PatientInDB_Then_ReturnNewPSforPatient(){ - - when(patientRepository.findByExternalIdAndGroup(EXTERNAL_ID, GROUP)) - .thenReturn(PATIENT); - - when(dataImportService.getPatientSnapshot(PATIENT, AGE_AT_COLLECTION)) - .thenReturn(actualSnapshot); - - actualSnapshot = dataImportService.getPatientSnapshot(EXTERNAL_ID, SEX, RACE, - ETHNICITY, AGE_AT_COLLECTION, GROUP); - - Assert.assertEquals(PATIENT, actualSnapshot.getPatient()); - Assert.assertEquals(AGE_AT_COLLECTION, actualSnapshot.getAgeAtCollection()); - } - @Test public void Given_getPatientSnapshot6Param_When_ValidArgAndNoPatientInDB_Then_ReturnMatchingPS(){ @@ -154,5 +159,16 @@ public class DataImportServiceTests extends BaseTest { } + @Test + public void Given_DataProjection_When_Save_Then_Saved(){ + + DataProjection dataProjection = new DataProjection(); + dataProjection.setLabel("test"); + when(dataProjectionRepository.save(any())).thenReturn(dataProjection); + Assert.assertEquals("test", dataImportService.saveDataProjection(dataProjection).getLabel()); + } + } + + diff --git a/data-services/src/test/java/org/pdxfinder/TestConfig.java b/data-services/src/test/java/org/pdxfinder/TestConfig.java index 265845167d5957275a2f3d85156865a003e6f457..ca06792597007118f8af3e0faea8dfbedd49dc87 100755 --- a/data-services/src/test/java/org/pdxfinder/TestConfig.java +++ b/data-services/src/test/java/org/pdxfinder/TestConfig.java @@ -2,9 +2,11 @@ package org.pdxfinder; import org.neo4j.ogm.session.SessionFactory; +import org.pdxfinder.configurations.DataServicesConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; @@ -14,11 +16,12 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.client.RestTemplate; -import org.thymeleaf.spring4.SpringTemplateEngine; -import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import javax.sql.DataSource; import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; /** @@ -27,7 +30,7 @@ import java.nio.charset.StandardCharsets; */ @Configuration @EnableTransactionManagement -@ComponentScan(value = "org.pdxfinder") +@ComponentScan(value = "org.pdxfinder", excludeFilters = @ComponentScan.Filter(type= FilterType.ASSIGNABLE_TYPE, classes = DataServicesConfig.class)) @EnableNeo4jRepositories("org.pdxfinder.graph.repositories") @EnableJpaRepositories(basePackages = "org.pdxfinder.rdbms.repositories") public class TestConfig { @@ -35,16 +38,11 @@ public class TestConfig { @Bean public org.neo4j.ogm.config.Configuration getConfiguration() { - org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); + org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration.Builder().build(); - // To persist the database, uncomment this section - // String pathToDb = Paths.get(".").toAbsolutePath().normalize().toString() + "/target/test_graph.db"; - // config - // .driverConfiguration() - // .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver") - // .setURI("file://" + pathToDb); - // - // System.out.println(config); + org.neo4j.ogm.config.Configuration configWithPersistance = new org.neo4j.ogm.config.Configuration.Builder() + .uri("file://" + Paths.get(".").toAbsolutePath().normalize().toString() + "/target/test_graph.db") + .build(); return config; } @@ -109,3 +107,4 @@ public class TestConfig { } + diff --git a/data-services/src/test/java/org/pdxfinder/services/DetailsServiceTest.java b/data-services/src/test/java/org/pdxfinder/services/DetailsServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..785623571d710560a62b21321d39dc10eecb3107 --- /dev/null +++ b/data-services/src/test/java/org/pdxfinder/services/DetailsServiceTest.java @@ -0,0 +1,106 @@ +package org.pdxfinder.services; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.MarkerAssociation; +import org.pdxfinder.graph.dao.MolecularCharacterization; +import org.pdxfinder.graph.dao.MolecularData; +import org.pdxfinder.graph.dao.Sample; +import org.pdxfinder.graph.repositories.MolecularCharacterizationRepository; +import org.pdxfinder.graph.repositories.SampleRepository; +import org.pdxfinder.services.dto.MolecularDataTableDTO; +import static org.mockito.Mockito.*; +import java.util.HashMap; +import java.util.Map; + +public class DetailsServiceTest extends BaseTest { + + @InjectMocks + private DetailsService detailsService; + + @Mock + MolecularCharacterizationRepository molecularCharacterizationRepository; + + @Mock + SampleRepository sampleRepository; + + @Mock + ReferenceDbService referenceDbService; + + Map<String, MolecularCharacterization> molchars; + Sample sample; + + @Before + public void init(){ + MockitoAnnotations.initMocks(this); + molchars = initMolchars(); + sample = new Sample(); + sample.setSourceSampleId("test"); + } + + @Test + public void given_MolcharId_When_GetMolcharTable_Then_CorrectContentReturned(){ + when(detailsService.getMolcharData("1")).thenReturn(molchars.get("1")); + when(detailsService.getMolcharData("2")).thenReturn(molchars.get("2")); + when(detailsService.getMolcharData("3")).thenReturn(molchars.get("3")); + when(sampleRepository.findSampleByMolcharId(anyLong())).thenReturn(sample); + when(referenceDbService.getReferenceData(any(), any())).thenReturn(new HashMap<>()); + MolecularDataTableDTO table1 = detailsService.getMolecularDataTable("1", false); + MolecularDataTableDTO table2 = detailsService.getMolecularDataTable("2", false); + MolecularDataTableDTO table3 = detailsService.getMolecularDataTable("3", false); + + Assert.assertEquals(3, table1.getMolecularDataRows().size()); + Assert.assertEquals(0, table2.getMolecularDataRows().size()); + Assert.assertEquals(0, table3.getMolecularDataRows().size()); + + } + + + + + private Map<String, MolecularCharacterization> initMolchars(){ + + Map<String, MolecularCharacterization> molecularCharacterizationMap = new HashMap(); + + MolecularCharacterization mc1 = new MolecularCharacterization(); + MarkerAssociation ma1 = new MarkerAssociation(); + ma1.setMolecularDataString("[{\"cytogeneticsResult\":\"postive\",\"marker\":\"ESR1\"},{\"cytogeneticsResult\":\"postive\",\"marker\":\"PGR\"},{\"cytogeneticsResult\":\"negative\",\"marker\":\"ERBB2\"}]"); + ma1.setDataPoints(3); + mc1.addMarkerAssociation(ma1); + mc1.setVisible(true); + + MolecularCharacterization mc2 = new MolecularCharacterization(); + MarkerAssociation ma2 = new MarkerAssociation(); + ma2.setMolecularDataString("[{\"cytogeneticsResult\":\"postive\",\"marker\":\"ESR1\"},{\"cytogeneticsResult\":\"postive\",\"marker\":\"PGR\"},{\"cytogeneticsResult\":\"negative\",\"marker\":\"ERBB2\"}]"); + ma2.setDataPoints(3); + mc2.addMarkerAssociation(ma2); + mc2.setVisible(false); + + MolecularCharacterization mc3 = new MolecularCharacterization(); + MarkerAssociation ma3 = new MarkerAssociation(); + ma3.setDataPoints(400); + mc3.setVisible(true); + + for(int i=0;i<400;i++){ + MolecularData md = new MolecularData(); + md.setMarker("ABC"); + md.setCytogeneticsResult("negative"); + ma3.addMolecularData(md); + } + ma3.encodeMolecularData(); + mc3.addMarkerAssociation(ma3); + + + molecularCharacterizationMap.put("1", mc1); + molecularCharacterizationMap.put("2", mc2); + molecularCharacterizationMap.put("3", mc3); + + return molecularCharacterizationMap; + } + +} diff --git a/data-services/src/test/java/org/pdxfinder/services/MappingServiceTest.java b/data-services/src/test/java/org/pdxfinder/services/MappingServiceTest.java index 0ff27f56f3878cae2bac490f9dc9a0a62e7a4f4e..11f675f0191096614da46aa59eedcbf6591a8aa6 100644 --- a/data-services/src/test/java/org/pdxfinder/services/MappingServiceTest.java +++ b/data-services/src/test/java/org/pdxfinder/services/MappingServiceTest.java @@ -6,6 +6,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.pdxfinder.BaseTest; import org.pdxfinder.rdbms.repositories.MappingEntityRepository; + import static org.mockito.Mockito.*; public class MappingServiceTest extends BaseTest { @@ -13,6 +14,9 @@ public class MappingServiceTest extends BaseTest { @Mock private MappingEntityRepository mappingEntityRepository; + @Mock + private UtilityService utilityService; + @InjectMocks private MappingService mappingService; @@ -32,6 +36,21 @@ public class MappingServiceTest extends BaseTest { } + @Test(expected = IllegalArgumentException.class) + public void given_directoryAttack_when_entityIsWrittenToFile_Then_throwArgumentException() { + mappingService.setRootDir("/tmp"); + String attackVector = "../../.."; + mappingService.writeMappingsToFile(attackVector); + } + + @Test + public void given_AplhaNumericAndHyphenatedDir_when_entityIsWrittenToFile_Then_doNotThrowArgumentException() { + mappingService.setRootDir("/tmp"); + String normalEntity= "TReatment-90_90-HELLO--"; + mappingService.writeMappingsToFile(normalEntity); + } + + } diff --git a/data-services/src/test/java/org/pdxfinder/services/MolcharTableTest.java b/data-services/src/test/java/org/pdxfinder/services/MolcharTableTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3308248925ec8b360c19d85cd4aae63aa9a23cd4 --- /dev/null +++ b/data-services/src/test/java/org/pdxfinder/services/MolcharTableTest.java @@ -0,0 +1,87 @@ +package org.pdxfinder.services; + +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.repositories.MolecularCharacterizationRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.List; + +/* + * Created by csaba on 18/03/2019. + */ +public class MolcharTableTest extends BaseTest{ + + + private final static Logger log = LoggerFactory.getLogger(MolcharTableTest.class); + + @Autowired + private MolecularCharacterizationRepository molecularCharacterizationRepository; + + List<Long> molcharNodeIds; + + @Before + public void setUp(){ + //log.info("Getting molchar node ids"); + //molcharNodeIds = molecularCharacterizationRepository.getAllMolCharIDs(); + + //log.info("Found "+molcharNodeIds.size()+ " molchar nodes"); + } + + + + @Test + public void visitAllMolcharUrls(){ + +/* + + for(Long id: molcharNodeIds){ + + } + + try{ + + String url = "/getmoleculardata/"+molcharNodeIds.get(0); + log.info("Getting data from: "+url); + String response = getText(url); + + System.out.println(response); + + } + catch (Exception e){ + e.printStackTrace(); + } + + + +*/ + } + + + public static String getText(String url) throws Exception { + URL website = new URL(url); + URLConnection connection = website.openConnection(); + BufferedReader in = new BufferedReader( + new InputStreamReader( + connection.getInputStream())); + + StringBuilder response = new StringBuilder(); + String inputLine; + + while ((inputLine = in.readLine()) != null) + response.append(inputLine); + + in.close(); + + return response.toString(); + + } + +} diff --git a/data-services/src/test/java/org/pdxfinder/services/PublicationServiceTest.java b/data-services/src/test/java/org/pdxfinder/services/PublicationServiceTest.java index 7180c511bcf87cedb224093ca0fde9fc46a60f76..9a04319602172486857f17670f0191e95dde8ea8 100644 --- a/data-services/src/test/java/org/pdxfinder/services/PublicationServiceTest.java +++ b/data-services/src/test/java/org/pdxfinder/services/PublicationServiceTest.java @@ -1,13 +1,8 @@ package org.pdxfinder.services; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.junit.Before; import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Mockito; import org.pdxfinder.BaseTest; import org.pdxfinder.services.constants.DataUrl; import org.pdxfinder.services.dto.europepmc.Publication; @@ -18,7 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; @@ -30,10 +24,9 @@ import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertSame; - -import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; -import static org.springframework.test.web.client.response.MockRestResponseCreators.*; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; public class PublicationServiceTest extends BaseTest { @@ -62,7 +55,7 @@ public class PublicationServiceTest extends BaseTest { // given String pubMedId = "29245952"; - String apiUrl = String.format("%s?query=%s&resultType=core&format=json", DataUrl.EUROPE_PMC_URL.get(), pubMedId); + String apiUrl = String.format("%s?query=ext_id:%s&resultType=core&format=json", DataUrl.EUROPE_PMC_URL.get(), pubMedId); String expectedTitle= "The humanized anti-human AMHRII mAb 3C23K exerts an anti-tumor activity against human ovarian cancer through tumor-associated macrophages."; String expectedAuthors= "Bougherara H, Némati F, Nicolas A, Massonnet G, Pugnière M, Ngô C, Le Frère-Belda MA"; diff --git a/data-services/src/test/java/org/pdxfinder/services/SearchServiceTest.java b/data-services/src/test/java/org/pdxfinder/services/SearchServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..96609da7d45059103ad3cb3fabefc0df9485ac3d --- /dev/null +++ b/data-services/src/test/java/org/pdxfinder/services/SearchServiceTest.java @@ -0,0 +1,41 @@ +package org.pdxfinder.services; + +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.repositories.SampleRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.util.Assert; + +/** + * Created by jmason on 06/07/2017. + */ +public class SearchServiceTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(SearchServiceTest.class); + + @MockBean + private SampleRepository sampleRepository; + + @Before + public void setup() { + // Preload the base data in the graph for testing the service + log.info("Set up"); + } + + @Test + public void searchForBreastCancerModels() throws Exception { + + log.info("Testing mock sample repository"); + Assert.notNull(sampleRepository, "Sample repo is null"); + + } + + @Test + public void anotherTest() { + log.info("This is another test"); + } + +} \ No newline at end of file diff --git a/data-services/src/test/java/org/pdxfinder/services/UtilityServiceTest.java b/data-services/src/test/java/org/pdxfinder/services/UtilityServiceTest.java index 4c2ae3ced2e570cc46b4be09bbba442cc63fd737..278fc52350d7af8237046fc73cc294e6fe1145cc 100644 --- a/data-services/src/test/java/org/pdxfinder/services/UtilityServiceTest.java +++ b/data-services/src/test/java/org/pdxfinder/services/UtilityServiceTest.java @@ -1,6 +1,5 @@ package org.pdxfinder.services; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -15,18 +14,13 @@ import org.mockito.InjectMocks; import org.pdxfinder.BaseTest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.multipart.MultipartFile; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; @@ -280,4 +274,16 @@ public class UtilityServiceTest extends BaseTest { // Then assertEquals(expected, actual); } + + @Test + public void given_CSV_When_Serialize_Then_FormatIsCorrect() throws Exception{ + + String mails = "test@example.com,test@example.net,john.doe@example.org"; + MultipartFile mockFile = new MockMultipartFile("mockFile", "test.csv", "text/csv", mails.getBytes("utf-8")); + + List<Map<String, String>> data = utilityService.serializeMultipartFile(mockFile); + Assert.assertEquals("text/csv", mockFile.getContentType()); + + + } } \ No newline at end of file diff --git a/data-services/src/test/java/org/pdxfinder/services/constants/DataProviderTest.java b/data-services/src/test/java/org/pdxfinder/services/constants/DataProviderTest.java deleted file mode 100644 index 6b3049d0320b38d6d340a426c764bcabd540b5e1..0000000000000000000000000000000000000000 --- a/data-services/src/test/java/org/pdxfinder/services/constants/DataProviderTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.pdxfinder.services.constants; - -import org.junit.Test; -import org.pdxfinder.BaseTest; - -import static org.junit.Assert.assertTrue; - -public class DataProviderTest extends BaseTest { - - private final static String ASSERTION_ERROR = "Unknown Data Provider Found: "; - - @Test - public void given_DataProviders_When_EnumListIsChanged_Then_Error() { - - boolean expected = true; - String message = ""; - - for (DataProvider option : DataProvider.values()) { - - switch (option) { - case Test_Minimal: - break; - case PDXNet_HCI_BCM: - break; - case IRCC_CRC: - break; - case JAX: - break; - case PDXNet_MDAnderson: - break; - case PDMR: - break; - case PDXNet_Wistar_MDAnderson_Penn: - break; - case PDXNet_WUSTL: - break; - case CRL: - break; - case Curie_BC: - break; - case Curie_LC: - break; - case Curie_OC: - break; - case IRCC_GC: - break; - case PMLB: - break; - case TRACE: - break; - case UOC_BC: - break; - case UOM_BC: - break; - case VHIO_BC: - break; - case VHIO_CRC: - break; - case DFCI_CPDM: - break; - case NKI: - break; - case PIPELINE: - break; - case JAX_XDOG: - break; - case SJCRH: - break; - case UMCG: - break; - case VHIO_PC: - break; - case LIH: - break; - default: - message = String.format("%s %s", ASSERTION_ERROR, option); - expected = false; - } - - assertTrue(message, expected); - } - - } - -} diff --git a/data-services/src/test/java/org/pdxfinder/services/ds/SearchDSTest.java b/data-services/src/test/java/org/pdxfinder/services/ds/SearchDSTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8308e893601d835d1f4ebe19e8708e9abf524adb --- /dev/null +++ b/data-services/src/test/java/org/pdxfinder/services/ds/SearchDSTest.java @@ -0,0 +1,140 @@ +package org.pdxfinder.services.ds; + +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.DataProjection; +import org.pdxfinder.graph.repositories.DataProjectionRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class SearchDSTest extends BaseTest { + + private final static Logger log = LoggerFactory.getLogger(SearchDSTest.class); + + @Autowired + SearchDS searchDS; + + @Autowired + DataProjectionRepository dataProjectionRepository; + + + private Set<ModelForQuery> models = new HashSet<>(); + + @Before + public void setUp() { + + ModelForQuery m = new ModelForQuery(); + m.setModelId(1L); + m.setPatientAge("TEST FILTER"); + m.setPatientGender("Male"); + models.add(m); + + m = new ModelForQuery(); + m.setModelId(2L); + m.setPatientAge("TEST FILTER 2"); + m.setPatientGender("Female"); + models.add(m); + + m = new ModelForQuery(); + m.setModelId(3L); + m.setPatientAge("TEST FILTER 3"); + m.setPatientGender("Male"); + models.add(m); + + m = new ModelForQuery(); + m.setModelId(4L); + m.setPatientAge("TEST FILTER 4"); + m.setPatientGender("Male"); + models.add(m); + + DataProjection dp = new DataProjection(); + dp.setLabel("ModelForQuery"); + dp.setValue("[" + + "{\"modelId\":164005,\"datasource\":\"PDXNet-WUSTL\",\"externalId\":\"WUSTL 911-06\",\"patientAge\":\"30-39\",\"patientGender\":\"Female\",\"sampleOriginTissue\":\"Not Specified\",\"sampleSampleSite\":\"Not Specified\",\"sampleExtractionMethod\":\"surgical sample\",\"sampleClassification\":\"ypT3/N1b/M1a/G1/G2\",\"sampleTumorType\":\"Primary\",\"cancerSystem\":[\"Unclassified\"],\"diagnosis\":\"Adenocarcinoma\",\"mappedOntologyTerm\":\"Adenocarcinoma\",\"treatmentHistory\":\"Not Specified\",\"allOntologyTermAncestors\":[\"Adenocarcinoma\",\"Carcinoma\",\"Epithelial Neoplasm\",\"Cancer\",\"Glandular Cell Neoplasm\",\"Neoplasm by Morphology\"]}," + + "{\"modelId\":158929,\"datasource\":\"JAX\",\"externalId\":\"J000104117\",\"patientAge\":\"60-69\",\"patientGender\":\"Female\",\"sampleOriginTissue\":\"Colon\",\"sampleSampleSite\":\"Abdominal wall\",\"sampleExtractionMethod\":\"Biopsy (type unspecified)\",\"sampleClassification\":\"AJCC IV/\",\"sampleTumorType\":\"Metastatic\",\"cancerSystem\":[\"Digestive System Cancer\"],\"diagnosis\":\"colon adenocarcinoma\",\"mappedOntologyTerm\":\"Colon Adenocarcinoma\",\"treatmentHistory\":\"Not Specified\",\"dataAvailable\":[\"CTP\"],\"allOntologyTermAncestors\":[\"Adenocarcinoma\",\"Colorectal Adenocarcinoma\",\"Colorectal Neoplasm\",\"Carcinoma\",\"Colon Neoplasm\",\"Colorectal Cancer\",\"Digestive System Carcinoma\",\"Colon Carcinoma\",\"Intestinal Cancer\",\"Neoplasm by Morphology\",\"Neoplasm by Site\",\"Colorectal Carcinoma\",\"Colon Cancer\",\"Intestinal Neoplasm\",\"Epithelial Neoplasm\",\"Digestive System Cancer\",\"Colon Adenocarcinoma\",\"Digestive System Neoplasm\",\"Glandular Cell Neoplasm\",\"Cancer\"]}" + + "]"); + + DataProjection mutDP = new DataProjection(); + mutDP.setLabel("PlatformMarkerVariantModel"); + mutDP.setValue("{\"TargetedNGS_MUT\":{\"RB1\":{\"N123D\":[10411],\"Q383E\":[10940],\"E323Q\":[16519],\"G38S\":[12539]}}}"); + + + DataProjection drugDP = new DataProjection(); + drugDP.setLabel("DrugResponse"); + drugDP.setValue("{}"); + + dataProjectionRepository.save(dp); + dataProjectionRepository.save(mutDP); + dataProjectionRepository.save(drugDP); + + assertThat(models.size(), is(4)); + + } + + @Test + public void getExactMatchDisjunctionPredicateTest() { + + List<String> filters = Arrays.asList("TEST FILTER", "TEST FILTER 2"); + Predicate pred = searchDS.getExactMatchDisjunctionPredicate(filters); + + Set<ModelForQuery> results = new HashSet<>(models); + Set<ModelForQuery> filteredResults = results.stream().filter(x -> pred.test(x.getPatientAge())).collect(Collectors.toSet()); + assertThat(filteredResults.size(), is(2)); + + } + + @Test + public void testCombinedFilters() { + + List<String> patientAgefilters = Arrays.asList("TEST FILTER", "TEST FILTER 2"); + Predicate predAge = searchDS.getExactMatchDisjunctionPredicate(patientAgefilters); + + List<String> patientGenderfilters = Arrays.asList("Female"); + Predicate predGender = searchDS.getExactMatchDisjunctionPredicate(patientGenderfilters); + + + Set<ModelForQuery> results = new HashSet<>(models); + + Set<ModelForQuery> filteredResults = results.stream().filter(x -> predAge.test(x.getPatientAge())).collect(Collectors.toSet()); + assertThat(filteredResults.size(), is(2)); + + filteredResults = filteredResults.stream().filter(x -> predGender.test(x.getPatientGender())).collect(Collectors.toSet()); + assertThat(filteredResults.size(), is(1)); + + + // Test applying the filters in another order to ensure the same result comes a the end + + filteredResults = results.stream().filter(x -> predGender.test(x.getPatientGender())).collect(Collectors.toSet()); + assertThat(filteredResults.size(), is(1)); + + filteredResults = filteredResults.stream().filter(x -> predAge.test(x.getPatientAge())).collect(Collectors.toSet()); + assertThat(filteredResults.size(), is(1)); + + assertThat(new ArrayList<>(filteredResults).get(0).getModelId(), is(2L)); + + log.info("Result after filtering is ", filteredResults); + + + } + + @Test + public void testGetDiagnosisCounts() { + searchDS.init(); + Map<String, Integer> diagnosisCounts = searchDS.getDiagnosisCounts(); + System.out.println(diagnosisCounts); + assertThat(diagnosisCounts.get("Adenocarcinoma"), is(2)); + assertThat(diagnosisCounts.get("Colon Adenocarcinoma"), is(1)); + + } + + +} \ No newline at end of file diff --git a/data-services/src/test/java/org/pdxfinder/services/loader/LoadMarkerTest.java b/data-services/src/test/java/org/pdxfinder/services/loader/LoadMarkerTest.java index 7cdd518668981efc7b125539363cec5f406919a7..2e2664ddf9be50e841bb77a640093b8511f431d7 100644 --- a/data-services/src/test/java/org/pdxfinder/services/loader/LoadMarkerTest.java +++ b/data-services/src/test/java/org/pdxfinder/services/loader/LoadMarkerTest.java @@ -10,10 +10,9 @@ import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.constants.DataUrl; import org.pdxfinder.services.loader.envload.LoadMarkers; -import java.io.IOException; - import static org.mockito.Matchers.anyListOf; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; public class LoadMarkerTest extends BaseTest { diff --git a/data-services/src/test/resources/logback.xml b/data-services/src/test/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..6a89304411c6f7825c0392d1c5b6318dc0e688c1 --- /dev/null +++ b/data-services/src/test/resources/logback.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <include resource="org/springframework/boot/logging/logback/base.xml"/> + <logger name="org.springframework" level="WARN"/> + <logger name="org.springframework.data.neo4j.mapping.Neo4jPersistentProperty" level="ERROR"/> + <logger name="org.neo4j" level="WARN"/> +</configuration> \ No newline at end of file diff --git a/data-services/src/test/resources/ogm.properties b/data-services/src/test/resources/ogm.properties new file mode 100644 index 0000000000000000000000000000000000000000..5cb8c7a63424763060cc283b3477637d1d2f1a81 --- /dev/null +++ b/data-services/src/test/resources/ogm.properties @@ -0,0 +1,4 @@ +# +# Configuration for embedded neo4j for tests +# +driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver \ No newline at end of file diff --git a/data-services/target/maven-archiver/pom.properties b/data-services/target/maven-archiver/pom.properties deleted file mode 100644 index f1e8bfe9c686f50755faa26fa588c6dd1b6dad25..0000000000000000000000000000000000000000 --- a/data-services/target/maven-archiver/pom.properties +++ /dev/null @@ -1,5 +0,0 @@ -#Generated by Apache Maven -#Mon Sep 23 13:05:56 CEST 2019 -groupId=org.pdxfinder -artifactId=data-services -version=1.0.0 diff --git a/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 9c35f3d90108207a41390f8ecc20c254f2ccdfea..0000000000000000000000000000000000000000 --- a/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,120 +0,0 @@ -org/pdxfinder/services/PaginationService.class -org/pdxfinder/services/search/OneParamTextFilter.class -org/pdxfinder/services/dto/LoaderDTO.class -org/pdxfinder/services/ds/SearchDS.class -org/pdxfinder/services/UtilityService.class -org/pdxfinder/services/Statistics.class -org/pdxfinder/services/highchart/HexColors.class -org/pdxfinder/services/pdf/Lists.class -org/pdxfinder/services/search/TwoParamUnlinkedFilter.class -org/pdxfinder/services/search/OneParamCheckboxSearch.class -org/pdxfinder/services/dto/MolecularDataTableDTO.class -org/pdxfinder/services/highchart/Column.class -org/pdxfinder/services/dto/QualityControlDTO.class -org/pdxfinder/services/PdfService.class -org/pdxfinder/services/dto/VariationDataDTO.class -org/pdxfinder/services/reporting/MarkerLogEntity.class -org/pdxfinder/services/pdf/PdfHelper.class -org/pdxfinder/services/ds/AutoCompleteOption.class -org/pdxfinder/services/search/WebFacetContainer.class -org/pdxfinder/services/mapping/CSV.class -org/pdxfinder/services/ds/SearchDS$6.class -org/pdxfinder/services/search/OneParamTextSearch.class -org/pdxfinder/services/ds/SearchFacetName.class -org/pdxfinder/services/search/OneParamLinkedFilter.class -org/pdxfinder/services/PlatformService.class -org/pdxfinder/services/highchart/Marker.class -org/pdxfinder/services/ds/ModelForQuery$1.class -org/pdxfinder/services/dto/StatisticsDTO.class -org/pdxfinder/services/DrugService.class -org/pdxfinder/services/mapping/MappingEntityType.class -org/pdxfinder/services/dto/KeyValuePairDTO.class -org/pdxfinder/services/pdf/Table.class -org/pdxfinder/services/MolCharService.class -org/pdxfinder/services/highchart/Labels.class -org/pdxfinder/services/SearchService.class -org/pdxfinder/services/highchart/Title.class -org/pdxfinder/services/search/FilterType.class -org/pdxfinder/services/dto/DetailsDTO.class -org/pdxfinder/services/highchart/SeriesType.class -org/pdxfinder/services/highchart/ToolTip.class -org/pdxfinder/services/highchart/XAxis.class -org/pdxfinder/services/search/OneParamLinkedSearch.class -org/pdxfinder/services/PatientService.class -org/pdxfinder/services/SearchService$1.class -org/pdxfinder/services/ds/Standardizer.class -org/pdxfinder/utils/DamerauLevenshteinAlgorithm.class -org/pdxfinder/services/search/ThreeParamLinkedSearch.class -org/pdxfinder/services/dto/TreatmentSummaryDTO.class -org/pdxfinder/services/ontology/OntoliaMatrix.class -org/pdxfinder/services/search/TwoParamUnlinkedSearch.class -org/pdxfinder/services/pdf/Column.class -org/pdxfinder/services/search/OneParamCheckboxFilter.class -org/pdxfinder/services/email/EmailConfig.class -org/pdxfinder/services/highchart/Chart.class -org/pdxfinder/services/search/ComparisonOperator.class -org/pdxfinder/services/ds/Harmonizer.class -org/pdxfinder/services/dto/PaginationDTO.class -org/pdxfinder/services/EmailService.class -org/pdxfinder/services/ds/SearchDS$1.class -org/pdxfinder/services/highchart/DataLabels.class -org/pdxfinder/services/highchart/Style.class -org/pdxfinder/services/highchart/Subtitle.class -org/pdxfinder/services/ds/SearchDS$5.class -org/pdxfinder/services/search/ThreeParamLinkedFilter.class -org/pdxfinder/services/search/TwoParamLinkedFilter.class -org/pdxfinder/services/mapping/Status.class -org/pdxfinder/services/pdf/Text.class -org/pdxfinder/services/highchart/PieData.class -org/pdxfinder/services/highchart/Item.class -org/pdxfinder/services/highchart/ChartStrings.class -org/pdxfinder/services/dto/PatientDTO.class -org/pdxfinder/services/reporting/LogEntityType.class -org/pdxfinder/services/pdf/Label.class -org/pdxfinder/services/dto/DrugSummaryDTO.class -org/pdxfinder/services/dto/NodeSuggestionDTO.class -org/pdxfinder/services/ds/ModelForQueryExport.class -org/pdxfinder/services/search/OneParamFilter.class -org/pdxfinder/services/email/EmailConstant.class -org/pdxfinder/services/search/WebFacetSection.class -org/pdxfinder/services/dto/CountDTO.class -org/pdxfinder/services/highchart/ChartHelper.class -org/pdxfinder/services/dto/CollectionEventsDTO.class -org/pdxfinder/services/highchart/Options3d.class -org/pdxfinder/services/dto/EngraftmentDataDTO.class -org/pdxfinder/services/search/FourParamLinkedFilter.class -org/pdxfinder/services/pdf/TableLayout.class -org/pdxfinder/services/ds/SearchDS$2.class -org/pdxfinder/services/pdf/Report.class -org/pdxfinder/services/reporting/LogEntity.class -org/pdxfinder/services/MappingService.class -org/pdxfinder/services/highchart/YAxis.class -org/pdxfinder/services/search/TwoParamLinkedSearch.class -org/pdxfinder/services/dto/SearchDTO.class -org/pdxfinder/services/highchart/ChartData.class -org/pdxfinder/services/highchart/PlotOptions.class -org/pdxfinder/services/dto/DataAvailableDTO.class -org/pdxfinder/services/DetailsService.class -org/pdxfinder/services/ds/SearchDS$3.class -org/pdxfinder/services/search/GeneralSearch.class -org/pdxfinder/services/email/Mail.class -org/pdxfinder/services/ontology/Ontolia.class -org/pdxfinder/services/dto/PlatformDataDTO.class -org/pdxfinder/services/dto/ExportDTO.class -org/pdxfinder/services/mapping/CSVHandler.class -org/pdxfinder/services/highchart/Series.class -org/pdxfinder/services/GraphService.class -org/pdxfinder/services/ds/FacetOption.class -org/pdxfinder/services/AutoCompleteService.class -org/pdxfinder/services/DataImportService.class -org/pdxfinder/services/search/OneParamSearch.class -org/pdxfinder/services/pdf/CanvasLine.class -org/pdxfinder/services/ontology/OntoliaMatrixRow.class -org/pdxfinder/services/dto/MolecularDataEntryDTO.class -org/pdxfinder/services/pdf/Style.class -org/pdxfinder/services/dto/WebSearchDTO.class -org/pdxfinder/services/ds/ModelForQuery.class -org/pdxfinder/services/search/FourParamLinkedSearch.class -org/pdxfinder/services/highchart/Pie.class -org/pdxfinder/services/ds/SearchDS$4.class -org/pdxfinder/services/search/GeneralFilter.class diff --git a/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 5633912428684bea337943cb8b051f2bcaa7281b..0000000000000000000000000000000000000000 --- a/data-services/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,112 +0,0 @@ -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/AutoCompleteOption.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/DrugService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/CanvasLine.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamTextFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/SearchDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/PdfService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/FilterType.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/CollectionEventsDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Lists.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/mapping/CSV.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/ThreeParamLinkedSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/PaginationDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/utils/DamerauLevenshteinAlgorithm.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/GraphService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/ExportDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/reporting/LogEntityType.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/UtilityService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/XAxis.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/ModelForQuery.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/PieData.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamLinkedSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/PaginationService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/Statistics.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Text.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/EmailService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/FourParamLinkedFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/TwoParamLinkedSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/CountDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamCheckboxFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/PatientService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamLinkedFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/WebSearchDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/ChartData.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Marker.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/Standardizer.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/TwoParamUnlinkedSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/QualityControlDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/PatientDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/StatisticsDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Labels.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/TwoParamUnlinkedFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/ChartHelper.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/ToolTip.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/VariationDataDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/AutoCompleteService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/ComparisonOperator.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/GeneralSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/ChartStrings.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Style.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/DataImportService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/MolecularDataEntryDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Column.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/MolCharService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/GeneralFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Table.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ontology/OntoliaMatrix.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/LoaderDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/PlatformDataDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Chart.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/WebFacetSection.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Label.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/PdfHelper.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/email/Mail.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/FacetOption.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/email/EmailConfig.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/DetailsService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/PlotOptions.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/mapping/MappingEntityType.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/EngraftmentDataDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/PlatformService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/DataAvailableDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/Harmonizer.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/SearchFacetName.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Title.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/HexColors.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ontology/Ontolia.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/YAxis.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/email/EmailConstant.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/TreatmentSummaryDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/TwoParamLinkedFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Subtitle.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/DataLabels.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Column.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Options3d.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/WebFacetContainer.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/ThreeParamLinkedFilter.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/SearchService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Pie.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/FourParamLinkedSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/mapping/Status.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Series.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Style.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/DetailsDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/reporting/LogEntity.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/NodeSuggestionDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/SeriesType.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/MolecularDataTableDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/Report.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/search/OneParamTextSearch.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ontology/OntoliaMatrixRow.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/mapping/CSVHandler.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/KeyValuePairDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/highchart/Item.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/dto/DrugSummaryDTO.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/MappingService.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/pdf/TableLayout.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/reporting/MarkerLogEntity.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/SearchDS.java -/home/luboslav/Desktop/dataportal-sourcecode/data-services/src/main/java/org/pdxfinder/services/ds/ModelForQueryExport.java diff --git a/dependencies/pom.xml b/dependencies/pom.xml index a0fb4cc472e141773278ec26bba0d42333f82dbd..85202eaeb97b42d46fbfe3051310bc91e040427c 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -3,6 +3,12 @@ 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> + <parent> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.3.3.RELEASE</version> + <relativePath/> + </parent> <groupId>org.pdxfinder</groupId> <artifactId>dependencies</artifactId> @@ -12,17 +18,10 @@ <properties> <pdxfinder.version>${project.version}</pdxfinder.version> <java.version>1.8</java.version> - <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version> + <neo4j.version>3.1.8</neo4j.version> <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version> </properties> - <parent> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-parent</artifactId> - <version>1.5.8.RELEASE</version> - <relativePath/> - <!-- lookup parent from repository --> - </parent> <repositories> <repository> <id>spring-milestones</id> @@ -43,17 +42,11 @@ <dependencies> - <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-data-neo4j</artifactId> - </dependency> - <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> @@ -66,43 +59,69 @@ <optional>true</optional> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-mail</artifactId> + </dependency> - <!-- Override neo4j version --> <dependency> - <groupId>org.neo4j</groupId> - <artifactId>neo4j</artifactId> - <version>3.1.1</version> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> - <!-- Include javax.validation package --> <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-validator</artifactId> + <groupId>com.github.openjson</groupId> + <artifactId>openjson</artifactId> + <version>1.0.11</version> </dependency> <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - <version>2.8.0</version> + <groupId>org.apache.poi</groupId> + <artifactId>poi-ooxml</artifactId> + <version>3.15</version> </dependency> - <!-- Include java mail dependencies --> <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-mail</artifactId> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + <version>3.15</version> </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.6</version> + </dependency> + + + <dependency> <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-thymeleaf</artifactId> + <artifactId>spring-boot-starter-data-neo4j</artifactId> </dependency> + + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j</artifactId> + <version>3.5.20</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-core</artifactId> + <version>3.1.20</version> + </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-api</artifactId> + <version>3.1.20</version> + </dependency> </dependencies> <dependencyManagement> <dependencies> - <!-- version management for project internal dependencies --> <dependency> <groupId>org.pdxfinder</groupId> <artifactId>data-model</artifactId> diff --git a/documentation/details_pdxfinder.pdf b/documentation/details_pdxfinder.pdf deleted file mode 100644 index 2122f224158249bf606a5ad023772d59ed8e8709..0000000000000000000000000000000000000000 Binary files a/documentation/details_pdxfinder.pdf and /dev/null differ diff --git a/documentation/homepage_pdxfinder.pdf b/documentation/homepage_pdxfinder.pdf deleted file mode 100644 index 99aa2661a3a71d073ef48466a4689ea6d876f5e7..0000000000000000000000000000000000000000 Binary files a/documentation/homepage_pdxfinder.pdf and /dev/null differ diff --git a/documentation/search_pdxfinder.pdf b/documentation/search_pdxfinder.pdf deleted file mode 100644 index 2d2661cf9e9c1030689e068990600ed35c1b5e01..0000000000000000000000000000000000000000 Binary files a/documentation/search_pdxfinder.pdf and /dev/null differ diff --git a/dp-quick-run.sh b/dp-quick-run.sh new file mode 100755 index 0000000000000000000000000000000000000000..337a7c45876d3dd568efd6f8f08120599c8002f8 --- /dev/null +++ b/dp-quick-run.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +mvn clean package -DskipTests +java -jar web/target/web-1.0.0.jar +#goto http://localhost:8080/data/search diff --git a/indexer/pom.xml b/indexer/pom.xml index ee4b5edb3bcbb44808ba3a2e534978511c36cf21..474cd2b1a27cff3b8cb76594dc9a23b0d22900b1 100644 --- a/indexer/pom.xml +++ b/indexer/pom.xml @@ -21,32 +21,27 @@ </dependency> <dependency> - <groupId>commons-cli</groupId> - <artifactId>commons-cli</artifactId> - <version>1.3.1</version> + <groupId>org.pdxfinder</groupId> + <artifactId>data-services</artifactId> </dependency> <dependency> - <groupId>org.neo4j</groupId> - <artifactId>neo4j-ogm-embedded-driver</artifactId> - <version>2.1.1</version> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.3.1</version> </dependency> - <!-- For command line option parsing --> <dependency> <groupId>net.sf.jopt-simple</groupId> <artifactId>jopt-simple</artifactId> <version>4.8</version> </dependency> + <dependency> <groupId>info.picocli</groupId> <artifactId>picocli-spring-boot-starter</artifactId> <version>4.0.4</version> </dependency> - <dependency> - <groupId>org.pdxfinder</groupId> - <artifactId>data-services</artifactId> - </dependency> <dependency> <groupId>tech.tablesaw</groupId> @@ -54,6 +49,17 @@ <version>LATEST</version> </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-embedded-driver</artifactId> + <version>3.1.20</version> + </dependency> + <dependency> + <!-- WARNING, do not update db engine (stable: 1.4.197) cause compatibility issues, see https://github.com/h2database/h2database/issues/2078 --> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>1.4.197</version> + </dependency> </dependencies> <build> diff --git a/indexer/src/main/java/org/pdxfinder/DatasourceConfig.java b/indexer/src/main/java/org/pdxfinder/DatasourceConfig.java deleted file mode 100644 index b27d5dc89729b2d22353641321145765a94b34e3..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/DatasourceConfig.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.pdxfinder; - -import org.apache.commons.io.FileUtils; -import org.neo4j.ogm.session.SessionFactory; -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.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 org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; -import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; -import org.springframework.data.transaction.ChainedTransactionManager; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.sql.DataSource; -import java.io.File; -import java.io.IOException; - -@Configuration -@EnableNeo4jRepositories(basePackages = "org.pdxfinder.graph") -@EnableJpaRepositories(basePackages = "org.pdxfinder.rdbms", transactionManagerRef = "h2TransactionManager") -@EnableTransactionManagement -public class DatasourceConfig { - - private Logger log = LoggerFactory.getLogger(DatasourceConfig.class); - - /************************************************************************************************************* - * NEO4J GRAPH DATABASE CONFIGURATION * - **************************************************/ - - @Value("${spring.data.neo4j.uri}") - private String embeddedDataDir; - - @Value("${db-cache-dir}") - private String cacheDataDir; - - @Value("${db-refresh}") - private boolean embeddedDbRefresh; - - @Primary - @Bean - public SessionFactory sessionFactory() throws IOException { - - this.refreshEmbeddedDBFromCache(); - org.neo4j.ogm.config.Configuration config = new org.neo4j.ogm.config.Configuration(); - config - .driverConfiguration() - .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver") - .setURI(embeddedDataDir); - config.autoIndexConfiguration().setAutoIndex("assert"); - return new SessionFactory(config, "org.pdxfinder.graph"); - } - - - @Primary - @Bean(name = "neo4jTransactionManager") - public Neo4jTransactionManager transactionManager() throws IOException { - return new Neo4jTransactionManager(sessionFactory()); - } - - - /************************************************************************************************************* - * RELATIONAL DATABASE CONFIGURATION * - **************************************************/ - - @Bean(name = "dataSource") - @ConfigurationProperties(prefix = "spring.datasource") - public DataSource dataSource() { - return DataSourceBuilder - .create().build(); - } - - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - - @Autowired - @Bean(name = "h2TransactionManager") - public JpaTransactionManager h2TransactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) - throws Exception { - return new JpaTransactionManager(entityManagerFactory.getObject()); - } - - - /************************************************************************************************************* - * CHAINED TRANSACTION MANAGER FOR MULTIPLE DATA SOURCES * - *******************************************************************/ - - @Autowired - @Bean(name = "transactionManager") - public PlatformTransactionManager transactionManager(Neo4jTransactionManager neo4jTransactionManager, - JpaTransactionManager h2TransactionManager) { - return new ChainedTransactionManager( - h2TransactionManager, - neo4jTransactionManager - ); - } - - - private void refreshEmbeddedDBFromCache() throws IOException{ - - boolean dataDeleted = false; - String dataDir = embeddedDataDir.replace("file://", ""); - - if (embeddedDbRefresh) { - File data = new File(dataDir); - File cache = new File(cacheDataDir); - - if (data.isDirectory()){ - FileUtils.cleanDirectory(data); - dataDeleted = true; - } - - if (cache.isDirectory() && dataDeleted){ - FileUtils.copyDirectory(cache, data); - } - } - } - - - -} - - diff --git a/indexer/src/main/java/org/pdxfinder/LoadDiseaseOntology.java b/indexer/src/main/java/org/pdxfinder/LoadDiseaseOntology.java index dd7852e9673169ad41f61b840d50867f442313c3..34bc8dc4216f4e05aaee89172fd1518dd6f58109 100644 --- a/indexer/src/main/java/org/pdxfinder/LoadDiseaseOntology.java +++ b/indexer/src/main/java/org/pdxfinder/LoadDiseaseOntology.java @@ -2,8 +2,7 @@ package org.pdxfinder; import joptsimple.OptionParser; import joptsimple.OptionSet; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.OntologyTerm; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.UtilityService; diff --git a/indexer/src/main/java/org/pdxfinder/Loader.java b/indexer/src/main/java/org/pdxfinder/Loader.java index 3ef84967ecfffd7b6bf7abfd0dff8e537a7e6968..edbeac4b5c09b4adabe572ed32567e1417885236 100644 --- a/indexer/src/main/java/org/pdxfinder/Loader.java +++ b/indexer/src/main/java/org/pdxfinder/Loader.java @@ -1,45 +1,16 @@ - package org.pdxfinder; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.SpringApplication; +import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; +import org.springframework.boot.builder.SpringApplicationBuilder; @SpringBootApplication -@EnableNeo4jRepositories -@EnableTransactionManagement public class Loader { - private final static Logger log = LoggerFactory.getLogger(Loader.class); - public static void main(String[] args) throws Exception { - - if (args.length == 0) { - Options options = new Options(); - HelpFormatter formatter = new HelpFormatter(); - - Option createOpt = Option.builder("create") - .desc("Process all data and re-creates the base graph database" + - " with the basic nodes pre loaded" + - " (standard tissues, implantation details, background strains, etc.") - .build(); - Option loadOpt = Option.builder("load").desc("load command ").build(); - Option jaxOpt = Option.builder("loadJAX").desc("Load JAX PDX models from file.").build(); - - options.addOption(createOpt); - options.addOption(loadOpt); - options.addOption(jaxOpt); - - formatter.printHelp("Application", options); - } else { - SpringApplication.run(Loader.class, args); - } + new SpringApplicationBuilder(Loader.class) + .web(WebApplicationType.NONE) + .run(args); } } diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TSV.java b/indexer/src/main/java/org/pdxfinder/TSV.java similarity index 69% rename from indexer/src/main/java/org/pdxfinder/dataloaders/updog/TSV.java rename to indexer/src/main/java/org/pdxfinder/TSV.java index e992f45eb9a99f25b7126c977407e227db102a60..fcf53ebab98f472aa21fd14aae9834a118aeadcc 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TSV.java +++ b/indexer/src/main/java/org/pdxfinder/TSV.java @@ -1,4 +1,4 @@ -package org.pdxfinder.dataloaders.updog; +package org.pdxfinder; public class TSV { @@ -167,4 +167,65 @@ public class TSV { model_id } + public enum providerFileNames{ + metadata, + sampleplatform, + cna, + mut, + expression, + patienttreatment, + cytogenetics, + drugdosing + } + + + public enum metadataSheetNames{ + checklist, + patient, + sample, + model, + model_validation, + sharing, + loader + } + + //Sample Platform sheet, these are the internal strings in the DB + public enum molecular_characterisation_type{ + + cyto("cytogenetics"), + expression("expression"), + mut("mutation"), + cna("copy number alteration"); + + public final String mcType; + + molecular_characterisation_type(String mcType) { this.mcType = mcType; } + } + + public enum numberOfMetadataSheets{ + numberSheets(6); + public final int count; + numberOfMetadataSheets(int count) { + this.count = count; + } + } + + public enum templateNames{ + metadata_template("metadata_template.xlsx"), + sampleplatform_template("sampleplatform_template.xlsx"), + patienttreatment_template("patienttreatment_template.xlsx"), + cna_template("cna_template.xlsx"), + expression_template("expression_template.xlsx"), + cytogenetics_template("cytogenetics_template.xlsx"), + mutation_template("mutation_template.xlsx"), + drugdosing_template("drugdosing_template.xlsx"); + + public final String fileName; + + templateNames(String fileName) { + this.fileName = fileName; + } + + } + } \ No newline at end of file diff --git a/indexer/src/main/java/org/pdxfinder/ValidateGeneSymbols.java b/indexer/src/main/java/org/pdxfinder/ValidateGeneSymbols.java index 7dd7f4012ecc7257a4d14bca4765ad609a9f923c..eb0fb233a5192707c76223a0b9eee98f7c231f9a 100644 --- a/indexer/src/main/java/org/pdxfinder/ValidateGeneSymbols.java +++ b/indexer/src/main/java/org/pdxfinder/ValidateGeneSymbols.java @@ -1,10 +1,6 @@ package org.pdxfinder; -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONException; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.accessionidtatamodel.AccessionData; import org.pdxfinder.graph.dao.ModelCreation; import org.pdxfinder.services.DataImportService; @@ -13,9 +9,7 @@ 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.boot.CommandLineRunner; import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.io.BufferedReader; diff --git a/indexer/src/main/java/org/pdxfinder/commandline/FinderCommandLine.java b/indexer/src/main/java/org/pdxfinder/commandline/FinderCommandLine.java index 4f773a93c3feb7e9e070f2835e0fb2f6c25d9c90..4ff71473d1b3434c130c6c6fbcb18ff3a083b236 100644 --- a/indexer/src/main/java/org/pdxfinder/commandline/FinderCommandLine.java +++ b/indexer/src/main/java/org/pdxfinder/commandline/FinderCommandLine.java @@ -9,9 +9,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import picocli.CommandLine; +import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; import picocli.CommandLine.Option; -import picocli.CommandLine.ArgGroup; import java.io.File; import java.io.IOException; @@ -27,6 +27,7 @@ import java.util.concurrent.Callable; subcommands = { FinderCommandLine.Load.class, FinderCommandLine.Export.class, + FinderCommandLine.ExportMappings.class, FinderCommandLine.Transform.class, CommandLine.HelpCommand.class } @@ -150,14 +151,90 @@ public class FinderCommandLine implements Callable<Integer> { @Override public String toString() { - return new StringJoiner("\n", Load.class.getSimpleName() + "[\n", "\n]") - .add("dataDirectory=" + dataDirectory) - .add("clearCacheRequested=" + loadCacheRequested) - .add("datasetRequested=" + getListOfRequestedProviders()) - .toString(); + return new StringJoiner(", ", Load.class.getSimpleName() + "[", "]") + .add("dataDirectory=" + dataDirectory) + .add("initializeMappingDB=" + initializeMappingDB) + .add("validateOnlyRequested=" + validateOnlyRequested) + .add("postLoadRequested=" + postLoadRequested) + .add("springDataNeo4jUri='" + springDataNeo4jUri + "'") + .add("debReload='" + debReload + "'") + .add("springDatasourceUrl='" + springDatasourceUrl + "'") + .toString(); } } + @Component + @Order(value = -100) + @Command(name = "exportMapping", + description = "Exports a subset of mappings defined by a group", + mixinStandardHelpOptions = true, + exitCodeOnExecutionException = 34) + static class ExportMappings implements Callable<Integer>{ + + @Option( + names = {"-d", "--data-dir"}, + required = true, + description = "Path of the PDX Finder data directory " + + "(default: [${DEFAULT-VALUE}], set in application.properties)") + private File dataDirectory; + + @ArgGroup(multiplicity = "0..1") + ExportMappings.Exclusive datasetRequested = new ExportMappings.Exclusive(); + + static class Exclusive { + + @Option(names = {"-g", "--group"}, arity = "1", + description = "Load the data for groups of dataProvider (default: [${DEFAULT-VALUE}]). " + + "Accepted Values: [@|cyan ${COMPLETION-CANDIDATES} |@]") + private DataProviderGroup dataProviderGroup; + + @Option(names = {"-o", "--only"}, arity = "1..*", + description = "Load only the data for the listed dataProvider. " + + "Accepted Values: [@|cyan ${COMPLETION-CANDIDATES} |@]") + private DataProvider[] dataProvider; + + public DataProviderGroup getDataProviderGroup() { + return dataProviderGroup; + } + + public DataProvider[] getDataProvider() { + return dataProvider; + } + } + + @Autowired + FinderMappingExporter finderMappingExporter; + + @Override + public Integer call() throws Exception { + + List<DataProvider> providersRequested = getListOfRequestedProviders(); + finderMappingExporter.run(dataDirectory, providersRequested); + return 0; + } + + + + List<DataProvider> getListOfRequestedProviders() { + + Optional<DataProvider[]> dataProviders = Optional.ofNullable( + datasetRequested.getDataProvider() + ); + + Optional<DataProviderGroup> dataProviderGroup = Optional.ofNullable( + datasetRequested.getDataProviderGroup() + ); + + if (dataProviders.isPresent()) { + return Arrays.asList(dataProviders.get()); + } else if (dataProviderGroup.isPresent()) { + return DataProviderGroup.getProvidersFrom(dataProviderGroup.get()); + } else { + return new ArrayList<>(); + } + } + + } @Component @Order(value = -100) @@ -169,13 +246,19 @@ public class FinderCommandLine implements Callable<Integer> { @Autowired private FinderExporter finderExporter; - @Option( names = {"-d", "--data-dir"}, description = "Path of the PDX Finder data directory " + "(default: [${DEFAULT-VALUE}], set in application.properties)") private File dataDirectory; + @Option( + names = {"-o", "--harmonized"}, + description = "Exports the NCIT ontology information" + ) + private boolean isHarmonized; + + @ArgGroup(multiplicity = "0..1") Export.Exclusive datasetRequested = new Export.Exclusive(); static class Exclusive{ @@ -193,8 +276,8 @@ public class FinderCommandLine implements Callable<Integer> { private boolean loadAll; - public DataProvider getProvider() { - return provider; + public String getProvider() { + return Objects.nonNull(provider) ? provider.toString() : ""; } public boolean isLoadAll() { @@ -203,7 +286,7 @@ public class FinderCommandLine implements Callable<Integer> { } @Override public Integer call() throws IOException { - finderExporter.run(dataDirectory, datasetRequested.provider.toString(), datasetRequested.isLoadAll()); + finderExporter.run(dataDirectory, datasetRequested.getProvider(), datasetRequested.isLoadAll(), isHarmonized); return 0; } @@ -213,6 +296,7 @@ public class FinderCommandLine implements Callable<Integer> { .add("dataDirectory=" + dataDirectory) .add("Export provider" + datasetRequested.getProvider()) .add("Load all" + datasetRequested.isLoadAll()) + .add("Unharmonized" + isHarmonized) .toString(); } } diff --git a/indexer/src/main/java/org/pdxfinder/commandline/FinderExporter.java b/indexer/src/main/java/org/pdxfinder/commandline/FinderExporter.java index 3308d9fd22aa812a98677c7633be84ce6543840f..9cda96d830094ec7e6866e1f5d6840336c2576a3 100644 --- a/indexer/src/main/java/org/pdxfinder/commandline/FinderExporter.java +++ b/indexer/src/main/java/org/pdxfinder/commandline/FinderExporter.java @@ -4,7 +4,6 @@ import org.apache.commons.lang3.StringUtils; import org.pdxfinder.dataexport.UniversalDataExporter; import org.pdxfinder.graph.dao.Group; import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -24,21 +23,21 @@ public class FinderExporter { private File rootDir; private static final Logger log = LoggerFactory.getLogger(FinderExporter.class); - private UtilityService utilityService; private DataImportService dataImportService; + private UniversalDataExporter universalDataExporter; @Autowired - FinderExporter(UtilityService utilityService, DataImportService dataImportService){ - this.utilityService = utilityService; + FinderExporter(DataImportService dataImportService, UniversalDataExporter universalDataExporter){ this.dataImportService = dataImportService; + this.universalDataExporter = universalDataExporter; } - public void run(File dataDirectory, String provider, boolean loadAll) throws IOException { + public void run(File dataDirectory, String provider, boolean loadAll, boolean isHarmonized) throws IOException { resolveRootDir(dataDirectory); if(loadAll){ - exportAllGroups(rootDir); + exportAllGroups(rootDir, isHarmonized); } else if (StringUtils.isNotEmpty(provider)) { - export(rootDir, provider); + export(rootDir, provider, isHarmonized); } } @@ -52,26 +51,24 @@ public class FinderExporter { } } - public void exportAllGroups(File rootDir){ + public void exportAllGroups(File rootDir, boolean isUnharmonized){ List<Group> allProviders = dataImportService.getAllProviderGroups(); allProviders.forEach(g -> { try { - export(rootDir, g.getAbbreviation()); + export(rootDir, g.getAbbreviation(),isUnharmonized); } catch (IOException e) { log.error(Arrays.toString(e.getStackTrace())); } }); } - public void export(File rootDir, String dataSourceAbbrev) throws IOException { + public void export(File rootDir, String dataSourceAbbrev, boolean isHarmonized) throws IOException { Group ds = dataImportService.findProviderGroupByAbbrev(dataSourceAbbrev); if(ds == null) { log.error("Datasource {} not found. ",dataSourceAbbrev); return; } - UniversalDataExporter downDog = new UniversalDataExporter(dataImportService, utilityService); - downDog.init(rootDir + "/template", ds); - downDog.export(rootDir + "/export"); + universalDataExporter.exportAllFromGroup(rootDir.getAbsolutePath() + "/export", ds, isHarmonized, rootDir + "/template"); } public void setDefaultDirectory(String defaultDirectory) { diff --git a/indexer/src/main/java/org/pdxfinder/commandline/FinderLoader.java b/indexer/src/main/java/org/pdxfinder/commandline/FinderLoader.java index 428e9cabea995c4583b2e7e63f4030766ec28f53..b3679361de97d034ca4d63727a3c42ce6c708ccb 100644 --- a/indexer/src/main/java/org/pdxfinder/commandline/FinderLoader.java +++ b/indexer/src/main/java/org/pdxfinder/commandline/FinderLoader.java @@ -1,14 +1,13 @@ package org.pdxfinder.commandline; import org.apache.commons.collections4.CollectionUtils; -import org.pdxfinder.dataloaders.*; +import org.pdxfinder.dataloaders.LoadJAXData; import org.pdxfinder.dataloaders.updog.Updog; import org.pdxfinder.mapping.InitMappingDatabase; import org.pdxfinder.mapping.LinkSamplesToNCITTerms; import org.pdxfinder.mapping.LinkTreatmentsToNCITTerms; import org.pdxfinder.postload.CreateDataProjections; import org.pdxfinder.postload.SetDataVisibility; -import org.pdxfinder.postload.ValidateDB; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.constants.DataProvider; import org.pdxfinder.services.constants.DataProviderGroup; @@ -37,20 +36,14 @@ public class FinderLoader { private LoadNCIT loadNCIT; // DataProvider Loading Components - private LoadHCI loadHCI; private LoadJAXData loadJAXData; - private LoadMDAnderson loadMDAnderson; - private LoadWISTAR loadWISTAR; - private LoadWUSTL loadWUSTL; private Updog updog; // PostLoad Components - private LoadAdditionalDatasets loadAdditionalDatasets; private LinkSamplesToNCITTerms linkSamplesToNCITTerms; private LinkTreatmentsToNCITTerms linkTreatmentsToNCITTerms; private CreateDataProjections createDataProjections; private SetDataVisibility setDataVisibility; - private ValidateDB validateDB; private InitMappingDatabase initMappingDatabase; @@ -60,21 +53,13 @@ public class FinderLoader { public FinderLoader(LoadMarkers loadMarkers, LoadNCITDrugs loadNCITDrugs, LoadNCIT loadNCIT, - - LoadHCI loadHCI, LoadJAXData loadJAXData, - LoadMDAnderson loadMDAnderson, - LoadPDMRData loadPDMRData, - LoadWISTAR loadWISTAR, - LoadWUSTL loadWUSTL, Updog updog, - LoadAdditionalDatasets loadAdditionalDatasets, LinkSamplesToNCITTerms linkSamplesToNCITTerms, LinkTreatmentsToNCITTerms linkTreatmentsToNCITTerms, CreateDataProjections createDataProjections, SetDataVisibility setDataVisibility, - ValidateDB validateDB, DataImportService dataImportService, ApplicationContext applicationContext, InitMappingDatabase initMappingDatabase) { @@ -83,19 +68,13 @@ public class FinderLoader { this.loadNCITDrugs = loadNCITDrugs; this.loadNCIT = loadNCIT; - this.loadHCI = loadHCI; this.loadJAXData = loadJAXData; - this.loadMDAnderson = loadMDAnderson; - this.loadWISTAR = loadWISTAR; - this.loadWUSTL = loadWUSTL; this.updog = updog; - this.loadAdditionalDatasets = loadAdditionalDatasets; this.linkSamplesToNCITTerms = linkSamplesToNCITTerms; this.linkTreatmentsToNCITTerms = linkTreatmentsToNCITTerms; this.createDataProjections = createDataProjections; this.setDataVisibility = setDataVisibility; - this.validateDB = validateDB; this.initMappingDatabase = initMappingDatabase; @@ -181,23 +160,10 @@ public class FinderLoader { ) { List<DataProvider> updogProviders = DataProviderGroup.getProvidersFrom(DataProviderGroup.UPDOG); try { - switch (dataProvider) { - case PDXNet_HCI_BCM: - loadHCI.run(); - break; - case JAX: - loadJAXData.run(); - break; - case PDXNet_MDAnderson: - loadMDAnderson.run(); - break; - case PDXNet_Wistar_MDAnderson_Penn: - loadWISTAR.run(); - break; - case PDXNet_WUSTL: - loadWUSTL.run(); - break; - default: + if (dataProvider.equals(DataProvider.JAX)) { + loadJAXData.run(); + } + else{ if (updogProviders.contains(dataProvider)) { Path updogDirectory = Paths.get( dataDirectory.toString(), @@ -222,7 +188,6 @@ public class FinderLoader { linkTreatmentsToNCITTerms.run(); createDataProjections.run(); setDataVisibility.run(); - validateDB.run(); } } diff --git a/indexer/src/main/java/org/pdxfinder/commandline/FinderMappingExporter.java b/indexer/src/main/java/org/pdxfinder/commandline/FinderMappingExporter.java new file mode 100644 index 0000000000000000000000000000000000000000..8b95a9d56cdaf92e19abe8659260d093694d821b --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/commandline/FinderMappingExporter.java @@ -0,0 +1,41 @@ +package org.pdxfinder.commandline; + +import org.pdxfinder.services.MappingService; +import org.pdxfinder.services.constants.DataProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +@Component +public class FinderMappingExporter { + + @Autowired + MappingService mappingService; + + public void run(File dataDirectory, List<DataProvider> dataProviders){ + + System.out.println("OK"); + List<String> dataSourcesToExport = new ArrayList<>(); + + for(DataProvider dp: dataProviders) + dataSourcesToExport.add(dp.toString()); + + String diagnosisFileName = String.format("%s/mappings_out/diagnosis_mappings.json", dataDirectory.getPath()); + String treatmentFileName = String.format("%s/mappings_out/treatment_mappings.json", dataDirectory.getPath()); + + + mappingService.saveMappingsToFile( + diagnosisFileName, + mappingService.getMappingsByDSAndType(dataSourcesToExport, "diagnosis").getEntityList() + ); + + mappingService.saveMappingsToFile( + treatmentFileName, + mappingService.getMappingsByDSAndType(dataSourcesToExport, "treatment").getEntityList() + ); + + } +} diff --git a/indexer/src/main/java/org/pdxfinder/configuration/H2Configuration.java b/indexer/src/main/java/org/pdxfinder/configuration/H2Configuration.java new file mode 100644 index 0000000000000000000000000000000000000000..582b69cbeab398b2197ca7253d68fea58f9740de --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/configuration/H2Configuration.java @@ -0,0 +1,64 @@ +package org.pdxfinder.configuration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; +import org.springframework.data.transaction.ChainedTransactionManager; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; + +@Configuration +@EnableJpaRepositories( + basePackages = "org.pdxfinder.rdbms.repositories", + transactionManagerRef = "h2TransactionManager") +@EnableTransactionManagement +public class H2Configuration { + + @Value("${data-dir}") + private String dataDir; + + @Bean + @ConfigurationProperties("h2.datasource") + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + @Autowired + @Bean + public JpaTransactionManager h2TransactionManager( + LocalContainerEntityManagerFactoryBean entityManagerFactory + ) { + return new JpaTransactionManager(entityManagerFactory.getObject()); + } + + @Autowired + @Bean(name = "transactionManager") + public PlatformTransactionManager transactionManager( + Neo4jTransactionManager neo4jTransactionManager, + JpaTransactionManager h2TransactionManager + ) { + return new ChainedTransactionManager( + h2TransactionManager, + neo4jTransactionManager + ); + } + + +} + + diff --git a/indexer/src/main/java/org/pdxfinder/configuration/Neo4jConfiguration.java b/indexer/src/main/java/org/pdxfinder/configuration/Neo4jConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..9dbb1293bb60b09fef4f144b58b202dcd0cf3e84 --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/configuration/Neo4jConfiguration.java @@ -0,0 +1,77 @@ +package org.pdxfinder.configuration; + +import org.apache.commons.io.FileUtils; +import org.neo4j.ogm.session.SessionFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; +import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import java.io.File; +import java.io.IOException; + +@Configuration +@EnableNeo4jRepositories( + basePackages = "org.pdxfinder.graph.repositories", + transactionManagerRef = "neo4jTransactionManager") +@EnableTransactionManagement +public class Neo4jConfiguration { + + @Value("${spring.data.neo4j.uri}") + private String embeddedDataDir; + + @Value("${db-cache-dir}") + private String cacheDataDir; + + @Value("${db-refresh}") + private boolean embeddedDbRefresh; + + @Value("${data-dir}") + private String dataDir; + + @Bean + public SessionFactory sessionFactory() throws IOException { + refreshEmbeddedDBFromCache(); + return new SessionFactory(neo4jConfiguration(), "org.pdxfinder.graph"); + } + + private org.neo4j.ogm.config.Configuration neo4jConfiguration() { + return new org.neo4j.ogm.config.Configuration.Builder() + .uri(embeddedDataDir) + .autoIndex("assert") + .build(); + } + + @Primary + @Bean(name = "neo4jTransactionManager") + public Neo4jTransactionManager transactionManager() throws IOException { + return new Neo4jTransactionManager(sessionFactory()); + } + + + private void refreshEmbeddedDBFromCache() throws IOException{ + + boolean dataDeleted = false; + String dataDir = embeddedDataDir.replace("file://", ""); + + if (embeddedDbRefresh) { + File data = new File(dataDir); + File cache = new File(cacheDataDir); + + if (data.isDirectory()){ + FileUtils.cleanDirectory(data); + dataDeleted = true; + } + + if (cache.isDirectory() && dataDeleted){ + FileUtils.copyDirectory(cache, data); + } + } + } + +} + + diff --git a/indexer/src/main/java/org/pdxfinder/dataexport/ExporterTemplates.java b/indexer/src/main/java/org/pdxfinder/dataexport/ExporterTemplates.java new file mode 100644 index 0000000000000000000000000000000000000000..a0e0452f54813a87b3a59331425bd6fb18cbd28c --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/dataexport/ExporterTemplates.java @@ -0,0 +1,99 @@ +package org.pdxfinder.dataexport; + +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.pdxfinder.TSV; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class ExporterTemplates { + + private XSSFWorkbook metadataTemplate; + private XSSFWorkbook samplePlatformTemplate; + private XSSFWorkbook mutationTemplate; + private XSSFWorkbook cnaTemplate; + private XSSFWorkbook cytoTemplate; + private XSSFWorkbook exprTemplate; + private XSSFWorkbook drugTemplate; + private XSSFWorkbook patientTreatmentTemplate; + + private Map<String, XSSFWorkbook> templatesMap; + private String templateDir; + private boolean isHarmonized; + + + public ExporterTemplates(String templateDir, boolean isharmonized) throws IOException { + this.templateDir = templateDir; + this.templatesMap = new HashMap<>(); + this.isHarmonized = isharmonized; + + loadTemplates(); + adjustMetadataTemplateIfHarmonized(); + addAllSheetsToMap(); + } + + private void adjustMetadataTemplateIfHarmonized() { + if(isHarmonized){ + XSSFSheet sampleSheet = metadataTemplate.getSheet(TSV.metadataSheetNames.sample.name()); + for (Row row : sampleSheet) { + if (row.getLastCellNum() != -1){ + row.createCell(row.getLastCellNum(), CellType.STRING); + String nextCellValue = row.getCell(8).getStringCellValue(); + String harmonizedRowMessage = "PDX Finder Harmonized Diagnosis"; + row.getCell(8).setCellValue(harmonizedRowMessage); + for (int i = 9; i < (row.getLastCellNum()); i++) { + String previousCellValue = nextCellValue; + nextCellValue = row.getCell(i).getStringCellValue(); + row.getCell(i).setCellValue(previousCellValue); + } + } + } + } + } + + private XSSFWorkbook getWorkbookFromFS(String templatePath) throws IOException { + XSSFWorkbook workbook; + File file = new File(templatePath); + if (!file.exists()) throw new IOException(String.format("Template %s was not found", templatePath)); + try (FileInputStream fileInputStream = new FileInputStream(file)) { + workbook = new XSSFWorkbook(fileInputStream); + } catch (Exception e) { + throw new IOException(e); + } + return workbook; + } + + private void loadTemplates() throws IOException { + metadataTemplate = getWorkbookFromFS(templateDir+"/" + TSV.templateNames.metadata_template.fileName); + samplePlatformTemplate = getWorkbookFromFS(templateDir+"/" + TSV.templateNames.sampleplatform_template.fileName); + mutationTemplate = getWorkbookFromFS(templateDir+"/" + TSV.templateNames.mutation_template.fileName); + cnaTemplate = getWorkbookFromFS(templateDir+"/" + TSV.templateNames.cna_template.fileName); + cytoTemplate = getWorkbookFromFS(templateDir + "/" + TSV.templateNames.cytogenetics_template.fileName); + exprTemplate = getWorkbookFromFS(templateDir + "/" + TSV.templateNames.expression_template.fileName); + drugTemplate = getWorkbookFromFS(templateDir + "/" + TSV.templateNames.drugdosing_template.fileName); + patientTreatmentTemplate = getWorkbookFromFS(templateDir + "/" + TSV.templateNames.patienttreatment_template.fileName); + } + + private void addAllSheetsToMap() { + templatesMap.put(TSV.templateNames.metadata_template.name(),metadataTemplate); + templatesMap.put(TSV.templateNames.sampleplatform_template.name(),samplePlatformTemplate); + templatesMap.put(TSV.templateNames.mutation_template.name() ,mutationTemplate); + templatesMap.put(TSV.templateNames.cna_template.name() ,cnaTemplate); + templatesMap.put(TSV.templateNames.cytogenetics_template.name() ,cytoTemplate); + templatesMap.put(TSV.templateNames.expression_template.name() ,exprTemplate); + templatesMap.put(TSV.templateNames.drugdosing_template.name(), drugTemplate); + templatesMap.put(TSV.templateNames.patienttreatment_template.name(), patientTreatmentTemplate); + } + + public XSSFWorkbook getTemplate(String template){ + return templatesMap.get(template); + } + + public boolean isHarmonized(){ return this.isHarmonized; } +} diff --git a/indexer/src/main/java/org/pdxfinder/dataexport/MetadataSheets.java b/indexer/src/main/java/org/pdxfinder/dataexport/MetadataSheets.java new file mode 100644 index 0000000000000000000000000000000000000000..3373cba519e3d595720efc7445cc3b17cafd43b7 --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/dataexport/MetadataSheets.java @@ -0,0 +1,65 @@ +package org.pdxfinder.dataexport; + +import org.pdxfinder.TSV; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MetadataSheets { + + private List<List<String>> checklistDataExport; + private List<List<String>> patientSheetDataExport; + private List<List<String>> patientSampleSheetDataExport; + private List<List<String>> pdxModelSheetDataExport; + private List<List<String>> pdxModelValidationSheetDataExport; + private List<List<String>> sharingAndContactSheetDataExport; + private List<List<String>> loaderRelatedDataSheetDataExport; + + private Map<String, List<List<String>>> exportSheetsMap; + private List<List<String>> blankSheet; + + public MetadataSheets() { + initDataExportSheets(); + createExportSheetMap(); + initBlankSheet(); + } + + private void initDataExportSheets() { + exportSheetsMap = new HashMap<>(); + + checklistDataExport = new ArrayList<>(); + patientSheetDataExport = new ArrayList<>(); + patientSampleSheetDataExport = new ArrayList<>(); + pdxModelSheetDataExport = new ArrayList<>(); + pdxModelValidationSheetDataExport = new ArrayList<>(); + sharingAndContactSheetDataExport = new ArrayList<>(); + loaderRelatedDataSheetDataExport = new ArrayList<>(); + } + + private void createExportSheetMap() { + exportSheetsMap.put(TSV.metadataSheetNames.checklist.name(), checklistDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.patient.name(),patientSheetDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.sample.name(),patientSampleSheetDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.model.name(),pdxModelSheetDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.model_validation.name(),pdxModelValidationSheetDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.sharing.name(),sharingAndContactSheetDataExport); + exportSheetsMap.put(TSV.metadataSheetNames.loader.name(),loaderRelatedDataSheetDataExport); + } + + private void initBlankSheet() { + blankSheet = new ArrayList<>(); + List<String> blankList = new ArrayList<>(); + blankSheet.add(blankList); + } + + public List<List<String>> get(String exportSheets) { + return exportSheetsMap.getOrDefault(exportSheets, blankSheet); + } + + public void set(String enumName, List<List<String>> sheetData){ + exportSheetsMap.put(enumName, sheetData); + } + +} diff --git a/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExporter.java b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExporter.java index f8edf81dbfe0aaf6dc6a48601d90474248194941..40ba308f0fdaac4077b7ceed28711d8484d8cbd8 100644 --- a/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExporter.java +++ b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExporter.java @@ -1,1050 +1,162 @@ package org.pdxfinder.dataexport; -import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.pdxfinder.graph.dao.*; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.Group; +import org.pdxfinder.graph.dao.ModelCreation; import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; +import org.springframework.stereotype.Component; -import java.io.*; -import java.nio.file.Files; +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.List; - -/* - * Created by csaba on 02/10/2019. - */ -@Service +@Component public class UniversalDataExporter { private static final Logger log = LoggerFactory.getLogger(UniversalDataExporter.class); - - protected UtilityService utilityService; - protected DataImportService dataImportService; - - protected String templateDir; - - private List<List<String>> patientSheetDataExport; - private List<List<String>> patientTumorSheetDataExport; - private List<List<String>> patientTreatmentSheetDataExport; - private List<List<String>> pdxModelSheetDataExport; - private List<List<String>> pdxModelValidationSheetDataExport; - private List<List<String>> samplePlatformDescriptionSheetDataExport; - private List<List<String>> sharingAndContactSheetDataExport; - private List<List<String>> loaderRelatedDataSheetDataExport; - private List<List<String>> drugDosingSheetDataExport; - - private List<List<String>> mutationSheetDataExport; - private List<List<String>> cnaSheetDataExport; - private List<List<String>> cytogeneticsSheetDataExport; - private List<List<String>> expressionSheetDataExport; - - private Group ds; - - private static String notSpecified = "Not Specified"; - private static String patientOrigin = "patient"; + private UniversalDataWriterServices writerUtilities; + private UniversalDataExtractionServices extractionServices; + private DataImportService dataImportService; @Autowired - public UniversalDataExporter(DataImportService dataImportService, UtilityService utilityService) { - + UniversalDataExporter(UniversalDataWriterServices writerUtilities, UniversalDataExtractionServices extractionUtilities, DataImportService dataImportService){ + this.writerUtilities = writerUtilities; + this.extractionServices = extractionUtilities; this.dataImportService = dataImportService; - this.utilityService = utilityService; - - patientSheetDataExport = new ArrayList<>(); - patientTumorSheetDataExport = new ArrayList<>(); - pdxModelSheetDataExport = new ArrayList<>(); - pdxModelValidationSheetDataExport = new ArrayList<>(); - sharingAndContactSheetDataExport = new ArrayList<>(); - loaderRelatedDataSheetDataExport = new ArrayList<>(); - - samplePlatformDescriptionSheetDataExport = new ArrayList<>(); - - mutationSheetDataExport = new ArrayList<>(); - cnaSheetDataExport = new ArrayList<>(); - cytogeneticsSheetDataExport = new ArrayList<>(); - expressionSheetDataExport = new ArrayList<>(); } - public Group getDs() { - return ds; - } - - public void setDs(Group ds) { - this.ds = ds; - } - - public String getTemplateDir() { - return templateDir; - } - - public void setTemplateDir(String templateDir) { - this.templateDir = templateDir; - } - - public void init(String templateDir, Group ds){ - - this.templateDir = templateDir; - this.ds = ds; - - initPatientData(); - initPatientTumorAtCollection(); - initPdxModelDetails(); - initPdxModelValidations(); - initSharingAndContact(); - initLoaderRelatedData(); - - initSamplePlatformDescription(); - - initOmicData(); - } - - public void export(String exportDir) throws IOException { - - XSSFWorkbook metadataTemplate = getWorkbook(templateDir+"/metadata_template.xlsx"); - XSSFWorkbook samplePlatformTemplate = getWorkbook(templateDir+"/sampleplatform_template.xlsx"); - XSSFWorkbook mutationTemplate = getWorkbook(templateDir+"/mutation_template.xlsx"); - XSSFWorkbook cnaTemplate = getWorkbook(templateDir+"/cna_template.xlsx"); - XSSFWorkbook cytoTemplate = getWorkbook(templateDir + "/cytogenetics_template.xlsx"); - XSSFWorkbook exprTemplate = getWorkbook(templateDir + "/expression_template.xlsx"); - - if (metadataTemplate != null && noMetaDataSheetsAreNull()) { - updateSheetWithData(metadataTemplate.getSheetAt(1), patientSheetDataExport, 6, 2); - updateSheetWithData(metadataTemplate.getSheetAt(2), patientTumorSheetDataExport, 6, 2); - updateSheetWithData(metadataTemplate.getSheetAt(3), pdxModelSheetDataExport, 6, 2); - updateSheetWithData(metadataTemplate.getSheetAt(4), pdxModelValidationSheetDataExport, 6, 2); - updateSheetWithData(metadataTemplate.getSheetAt(5), sharingAndContactSheetDataExport, 6, 2); - updateSheetWithData(metadataTemplate.getSheetAt(6), loaderRelatedDataSheetDataExport, 6, 2); - } - - if (samplePlatformTemplate != null && samplePlatformDescriptionSheetDataExport != null) { - updateSheetWithData(samplePlatformTemplate.getSheetAt(0), samplePlatformDescriptionSheetDataExport, 6, 1); - } - - Path exportProviderDir = Paths.get(exportDir + "/" + ds.getAbbreviation()); - Files.createDirectories(exportProviderDir); + public void exportAllFromGroup(String exportDir, Group dataSource, boolean isHarmonized, String templateDir) throws IOException { + String exportProviderDir = Paths.get(String.format("%s/%s/",exportDir ,dataSource.getAbbreviation())).toString(); + ExporterTemplates templates = new ExporterTemplates(templateDir, isHarmonized); + MetadataSheets providerSheets = new MetadataSheets(); + writerUtilities.createExportDirectories(exportProviderDir); try { - if(metadataTemplate != null && noMetaDataSheetsAreNull()) { - writeFileFromWorkbook(metadataTemplate, exportProviderDir + "/metadata.xlsx"); - } - if(samplePlatformTemplate != null && samplePlatformDescriptionSheetDataExport != null) { - writeFileFromWorkbook(samplePlatformTemplate, exportProviderDir + "/sampleplatform.xlsx"); - } - writeOmicFileFromWorkbook(mutationTemplate, mutationSheetDataExport, exportProviderDir + "/mut/", "_mut.tsv"); - writeOmicFileFromWorkbook(cnaTemplate, cnaSheetDataExport, exportProviderDir + "/cna/", "_cna.tsv" ); - writeOmicFileFromWorkbook(cytoTemplate, cytogeneticsSheetDataExport, exportProviderDir + "/cyto/", "_cyto.tsv" ); - writeOmicFileFromWorkbook(exprTemplate, expressionSheetDataExport, exportProviderDir + "/expr/", "_expr.tsv"); - } catch (Exception e) { - log.error("error", e); - } - } - - private boolean noMetaDataSheetsAreNull(){ - return (patientSheetDataExport != null && patientTumorSheetDataExport != null - && pdxModelSheetDataExport != null && pdxModelValidationSheetDataExport != null - && sharingAndContactSheetDataExport != null && loaderRelatedDataSheetDataExport != null); - } - - private void writeFileFromWorkbook(XSSFWorkbook dataWorkbook, String fileLocation) throws IOException { - if (dataWorkbook != null) { - FileOutputStream fileOut = new FileOutputStream(fileLocation); - dataWorkbook.write(fileOut); - fileOut.close(); - } - } - - private void writeOmicFileFromWorkbook(XSSFWorkbook omicWorkbook,List<List<String>> exportSheet, String fileLocation, String suffix ) throws IOException { - if (omicWorkbook != null && exportSheet != null && !exportSheet.isEmpty()) { - if (!Paths.get(fileLocation).toFile().exists()) { - Files.createDirectory(Paths.get(fileLocation)); - } - String exportURI = fileLocation + ds.getAbbreviation() + suffix; - readSheetAndWriteOmicTsvFile(omicWorkbook.getSheetAt(0),exportSheet, exportURI); - } - } - - public void initPatientData() { - - if (ds == null) return; - - List<Patient> patients = dataImportService.findPatientsByGroup(ds); - - for (Patient patient : patients) { - - List<String> dataRow = new ArrayList<>(); - - String patientId = patient.getExternalId(); - String sex = patient.getSex(); - String cancerHistory = patient.getCancerRelevantHistory(); - String ethnicity = patient.getEthnicity(); - String ethnicityAssessment = patient.getEthnicityAssessment(); - String firstDiagnosis = patient.getFirstDiagnosis(); - String ageAtFirstDiagnosis = patient.getAgeAtFirstDiagnosis(); - - dataRow.add(patientId); - dataRow.add(sex); - dataRow.add(cancerHistory); - dataRow.add(ethnicity); - dataRow.add(ethnicityAssessment); - dataRow.add(firstDiagnosis); - dataRow.add(ageAtFirstDiagnosis); - - patientSheetDataExport.add(dataRow); - } - } - - public void initPatientTumorAtCollection(){ - - if (ds == null) return; - - List<Patient> patients = dataImportService.findPatientTumorAtCollectionDataByDS(ds); - - for(Patient patient : patients){ - - String patientId = patient.getExternalId(); - - for(PatientSnapshot patientSnapshot : patient.getSnapshots()){ - - for(Sample sample : patientSnapshot.getSamples()){ - - List<String> dataRow = new ArrayList<>(); - - String sampleId = sample.getSourceSampleId(); - String collectionDate = patientSnapshot.getDateAtCollection(); - String collectionEvent = patientSnapshot.getCollectionEvent(); - String elapsedTime = patientSnapshot.getElapsedTime(); - String ageAtCollection = patientSnapshot.getAgeAtCollection(); - String diagnosis = sample.getDiagnosis(); - String tumorType = sample.getType().getName(); - String primarySite = sample.getOriginTissue().getName(); - String collectionSite = sample.getSampleSite().getName(); - String stage = sample.getStage(); - String stageClassification = sample.getStageClassification(); - String grade = sample.getGrade(); - String gradeClassification = sample.getGradeClassification(); - String virologyStatus = patientSnapshot.getVirologyStatus(); - String isPatientTreatmentInfoAvailable = ""; - String treatmentNaive = patientSnapshot.getTreatmentNaive(); - String isPatientTreated = ""; - String wasPatientTreated = ""; - String modelId = ""; - try { - modelId = dataImportService.findModelBySample(sample).getSourcePdxId(); - } - catch (Exception e){ - log.error("Error getting model Id from sample: {}", sampleId); - } - - dataRow.add(patientId); - dataRow.add(sampleId); - dataRow.add(collectionDate); - dataRow.add(collectionEvent); - dataRow.add(elapsedTime); - dataRow.add(ageAtCollection); - dataRow.add(diagnosis); - dataRow.add(tumorType); - dataRow.add(primarySite); - dataRow.add(collectionSite); - dataRow.add(stage); - dataRow.add(stageClassification); - dataRow.add(grade); - dataRow.add(gradeClassification); - dataRow.add(virologyStatus); - dataRow.add(isPatientTreatmentInfoAvailable); - dataRow.add(treatmentNaive); - dataRow.add(isPatientTreated); - dataRow.add(wasPatientTreated); - dataRow.add(modelId); - - patientTumorSheetDataExport.add(dataRow); - } - } - } - - } - - public void initPdxModelDetails(){ - - if (ds == null) return; - - List<ModelCreation> models = dataImportService.findModelsWithSpecimensAndQAByDS(ds.getAbbreviation()); - - for(ModelCreation model : models){ - - Map<String, ModelDetails> specimenMap = new HashMap<>(); - - for(Specimen specimen : model.getSpecimens()){ - - String passage = specimen.getPassage(); - - String engraftmentSite = notSpecified; - - if(specimen.getEngraftmentSite() != null ){ - engraftmentSite = specimen.getEngraftmentSite().getName(); - } - - String engraftmentType = notSpecified; - - if(specimen.getEngraftmentType() != null){ - engraftmentType = specimen.getEngraftmentType().getName(); - } - - String engraftmentMaterial = notSpecified; - String engraftmentMaterialStatus = notSpecified; - - if(specimen.getEngraftmentMaterial() != null){ - engraftmentMaterial = specimen.getEngraftmentMaterial().getName(); - engraftmentMaterialStatus = specimen.getEngraftmentMaterial().getState(); - } - - addEntryToSpecimenMap( - specimenMap, - specimen.getHostStrain(), - engraftmentSite, - engraftmentType, - engraftmentMaterial, - engraftmentMaterialStatus, - passage); - } - - insertModelSheetDataFromSpecimenMap(specimenMap, model); - - } - } - - public void initPdxModelValidations(){ - - if (ds == null) return; - - List<ModelCreation> models = dataImportService.findModelsWithSpecimensAndQAByDS(ds.getAbbreviation()); - - for(ModelCreation model : models){ - - if(model != null && model.getQualityAssurance() != null) { - - String modelId = model.getSourcePdxId(); - - for (QualityAssurance qa : model.getQualityAssurance()) { - - List<String> dataRow = new ArrayList<>(); - - String validationTechnique = qa.getTechnology(); - String validationDescription = qa.getDescription(); - String passages = qa.getPassages(); - String nomenclature = qa.getValidationHostStrain(); - - dataRow.add(modelId); - dataRow.add(validationTechnique); - dataRow.add(validationDescription); - dataRow.add(passages); - dataRow.add(nomenclature); - - pdxModelValidationSheetDataExport.add(dataRow); - } - } - } - } - - public void initSharingAndContact(){ - - if (ds == null) return; - - List<ModelCreation> models = dataImportService.findModelsWithSharingAndContactByDS(ds.getAbbreviation()); - - for(ModelCreation model : models){ - - LinkedHashMap<String, String> sharingAndContactRow = new LinkedHashMap<>(); - - sharingAndContactRow.put("modelId", model.getSourcePdxId()); - - Group providerGroup = getGroupByType(model, "Provider"); - Group accessGroup = getGroupByType(model, "Accessibility"); - Group projectGroup = getGroupByType(model, "Project"); - - getGroupData(sharingAndContactRow, providerGroup, accessGroup, projectGroup); - - getExternalUrlData(sharingAndContactRow, model.getExternalUrls()); - - insertSharingAndContactDataForModel(sharingAndContactRow); - - } - } - - public void initLoaderRelatedData(){ - - if (ds == null) return; - - List<String> dataRow = new ArrayList<>(); - dataRow.add(ds.getName()); - dataRow.add(ds.getAbbreviation()); - dataRow.add(ds.getUrl()); - - loaderRelatedDataSheetDataExport.add(dataRow); - - } - - public void initSamplePlatformDescription(){ - - if (ds == null) return; - - List<ModelCreation> models = dataImportService.findModelXenograftPlatformSampleByDS(ds.getAbbreviation()); - - for(ModelCreation model : models){ - - addPatientMolcharDataToSamplePlatform(model); - addXenoMolcharDataToSamplePlatform(model); - } - - } - - public void initOmicData(){ - initGenomicData(mutationSheetDataExport, "mutation"); - initGenomicData(cnaSheetDataExport, "copy number alteration"); - initGenomicData(cytogeneticsSheetDataExport, "cytogenetics"); - initGenomicData(expressionSheetDataExport, "expression"); - } - - - private void initGenomicData(List<List<String>> sheetData, String molcharType){ - - //TODO, these queries could be optimized to reduce db interactions - List<ModelCreation> models = dataImportService.findModelsWithSharingAndContactByDS(ds.getAbbreviation()); - - for(ModelCreation m: models){ - ModelCreation model = dataImportService.findModelWithMolecularDataByDSAndIdAndMolcharType( - ds.getAbbreviation(), - m.getSourcePdxId(), - molcharType); - - if(model != null){ - - String modelId = model.getSourcePdxId(); - log.info("Exporting data for {}", modelId); - - initPatientGenomicData(model, sheetData); - initXenoGenomicData(model, sheetData); - } - } - } - - private void insertOmicDataToSheet( - ModelCreation model, - String sampleId, - String sampleOrigin, - String molcharType, - Specimen specimen, - MolecularCharacterization mc, - List<List<String>> sheetData){ - - for(MarkerAssociation ma: mc.getMarkerAssociations()){ - List<MolecularData> molecularData; - try{ - molecularData = ma.decodeMolecularData(); - } - catch(Exception e){ - log.error("No molecular data in Marker Association on Sample {}", sampleId); - molecularData = new ArrayList<>(); - } - for(MolecularData md : molecularData){ - List<String> rowData = new ArrayList<>(); - rowData.add(model.getSourcePdxId()); - rowData.add(sampleId); - rowData.add(sampleOrigin); - - if(sampleOrigin.equals(patientOrigin)){ - //no passage, host strain for patient samples - rowData.add(""); - rowData.add(""); - } - else{ - - rowData.add(specimen.getPassage()); - - if(specimen.getHostStrain() != null && specimen.getHostStrain().getSymbol() != null){ - rowData.add(specimen.getHostStrain().getSymbol()); - } - else{ - rowData.add(""); - } - } - - switch (molcharType) { - case "mutation": - rowData.add(md.getMarker()); - rowData.add(md.getAminoAcidChange()); - rowData.add(md.getBiotype()); - rowData.add(md.getCodingSequenceChange()); - rowData.add(md.getVariantClass()); - rowData.add(md.getNucleotideChange()); - rowData.add(md.getCodonChange()); - rowData.add(md.getAminoAcidChange()); - rowData.add(md.getConsequence()); - rowData.add(md.getReadDepth()); - rowData.add(md.getAlleleFrequency()); - rowData.add(md.getChromosome()); - rowData.add(md.getSeqStartPosition()); - rowData.add(md.getRefAllele()); - rowData.add(md.getAltAllele()); - rowData.add(md.getUcscGeneId()); - rowData.add(md.getNcbiGeneId()); - rowData.add(md.getNcbiTranscriptId()); - rowData.add(md.getEnsemblGeneId()); - rowData.add(md.getEnsemblTranscriptId()); - rowData.add(md.getExistingVariations()); - rowData.add(md.getGenomeAssembly()); - rowData.add(mc.getPlatform().getName()); - break; - case "copy number alteration": - rowData.add(md.getChromosome()); - rowData.add(md.getSeqStartPosition()); - rowData.add(md.getSeqEndPosition()); - rowData.add(md.getMarker()); - rowData.add(md.getUcscGeneId()); - rowData.add(md.getNcbiGeneId()); - rowData.add(md.getEnsemblGeneId()); - rowData.add(md.getCnaLog10RCNA()); - rowData.add(md.getCnaLog2RCNA()); - rowData.add(md.getFold_change()); - rowData.add(md.getCnaCopyNumberStatus()); - rowData.add(md.getCnaGisticValue()); - rowData.add(md.getCnaPicnicValue()); - rowData.add(md.getGenomeAssembly()); - rowData.add(mc.getPlatform().getName()); - break; - case "cytogenetics": - rowData.add(""); - rowData.add(md.getMarker()); - rowData.add(md.getCytogeneticsResult()); - rowData.add(md.getMarkerStatusComment()); - rowData.add(mc.getPlatform().getName()); - rowData.add(""); - rowData.add(""); - break; - case "expression": - rowData.add(md.getChromosome()); - rowData.add(""); - rowData.add(md.getSeqStartPosition()); - rowData.add(md.getSeqEndPosition()); - rowData.add(md.getMarker()); - rowData.add(""); - rowData.add(""); - rowData.add(""); - rowData.add(md.getRnaSeqCoverage()); - rowData.add(md.getRnaSeqFPKM()); - rowData.add(md.getRnaSeqTPM()); - rowData.add(md.getRnaSeqCount()); - rowData.add(md.getAffyHGEAProbeId()); - rowData.add(md.getAffyHGEAExpressionValue()); - rowData.add(md.getIlluminaHGEAProbeId()); - rowData.add(md.getIlluminaHGEAExpressionValue()); - rowData.add(md.getZscore()); - rowData.add(md.getGenomeAssembly()); - rowData.add(mc.getPlatform().getName()); - break; - default: - throw new IllegalArgumentException("Inappropriate Molecular data type passed"); - } - sheetData.add(rowData); - } - } - } - - public void updateSheetWithData(Sheet sheet, List<List<String>> data, int startRow, int startColumn) { - - //Workbook rows and cells start at index 0 - if (data != null) { - - for (int i = 0; i < data.size(); i++) { - - int rowIndex = startRow + i - 1; - sheet.createRow(rowIndex); - - for (int j = 0; j < data.get(i).size(); j++) { - - - int columnIndex = startColumn + j - 1; - sheet.getRow(rowIndex).createCell(columnIndex); - - - Cell cell; - try { - cell = sheet.getRow(rowIndex).getCell(columnIndex); - cell.setCellValue(data.get(i).get(j)); - } catch (Exception e) { - - log.error("Exception in {} {}:{}", sheet.getSheetName(), rowIndex, columnIndex); - } - } - } - } - } - - public void readSheetAndWriteOmicTsvFile(Sheet xlsxTemplate, List<List<String>> exportSheet, String omicTsvDir) { - - try(FileWriter fileWriter = new FileWriter(omicTsvDir)) { - if (exportSheet != null) { - copyHeadersFromSheetToTsv(xlsxTemplate,fileWriter); - writeDataToTsv(xlsxTemplate, exportSheet, fileWriter); - } - } catch(Exception e) { - log.error(String.format("IO Error from reading omic TSV %s",e.toString())); - } - } - - - private void copyHeadersFromSheetToTsv(Sheet xlsxTemplate, FileWriter fileWriter) throws IOException { - - for (int j = 0; j < xlsxTemplate.getRow(0).getLastCellNum(); j++) { - Cell cell; - try { - cell = xlsxTemplate.getRow(0).getCell(j); - fileWriter.append(cell.toString()); - fileWriter.append("\t"); - } catch (Exception e) { - log.error("Exception in loading export headers"); - } - } - fileWriter.append("\n"); - } - - private void writeDataToTsv(Sheet sheet, List<List<String>> data, FileWriter fileWriter) throws IOException { - for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { - for (int columnIndex = 0; columnIndex < data.get(rowIndex).size(); columnIndex++) { - try { - fileWriter.append(data.get(rowIndex).get(columnIndex)); - fileWriter.append("\t"); - } catch (IOException e) { - log.error("Exception in {} {}:{}", sheet.getSheetName(), rowIndex, columnIndex); - } - } - fileWriter.append("\n"); - } - } - - - private String getPubmedIDs(ModelCreation model){ - - StringBuilder pubmedIDs = new StringBuilder(); - - if(model.getGroups() != null){ - - for(Group g : model.getGroups()){ - - if(g.getType().equals("Publication")){ - - if(pubmedIDs.length() != 0){ - pubmedIDs.append(","); - } - - pubmedIDs.append(g.getPubMedId()); - } - } - } - - return pubmedIDs.toString(); - } - - private void insertModelSheetDataFromSpecimenMap(Map<String, ModelDetails> specimenMap, ModelCreation model){ - - String modelId = model.getSourcePdxId(); - - String pubmedIDs = getPubmedIDs(model); - - for(Map.Entry<String, ModelDetails> entry : specimenMap.entrySet()){ - - ModelDetails md = entry.getValue(); - List<String> dataRow = new ArrayList<>(); - - dataRow.add(modelId); - dataRow.add(md.getHostStrainName()); - dataRow.add(md.getHostStrainNomenclature()); - dataRow.add(md.getEngraftmentSite()); - dataRow.add(md.getEngraftmentType()); - dataRow.add(md.getEngraftmentMaterial()); - dataRow.add(md.getEngraftmentMaterialStatus()); - dataRow.add(md.getSortedPassages()); - dataRow.add(pubmedIDs); - - pdxModelSheetDataExport.add(dataRow); - } - } - - private void insertSharingAndContactDataForModel(LinkedHashMap<String, String> sharingAndContactRow){ - - if(sharingAndContactRow != null) { - - List<String> dataRow = new ArrayList<>(); - - dataRow.add(sharingAndContactRow.get("modelId")); - dataRow.add(sharingAndContactRow.get("providerType")); - dataRow.add(sharingAndContactRow.get("modelAccessibility")); - dataRow.add(sharingAndContactRow.get("accessModalities")); - dataRow.add(sharingAndContactRow.get("contactEmail")); - dataRow.add(sharingAndContactRow.get("contactName")); - dataRow.add(sharingAndContactRow.get("contactLink")); - dataRow.add(sharingAndContactRow.get("modelLink")); - dataRow.add(sharingAndContactRow.get("providerName")); - dataRow.add(sharingAndContactRow.get("providerAbbrev")); - dataRow.add(sharingAndContactRow.get("projectName")); - - sharingAndContactSheetDataExport.add(dataRow); - } - } - - private Group getGroupByType(ModelCreation model, String type){ - - if(model.getGroups() != null){ - - for(Group g : model.getGroups()){ - - if(g.getType().equals(type)){ - return g; - } - } - } - - return null; - } - - private void getGroupData(LinkedHashMap<String, String> map, Group providerGroup, Group accessGroup, Group projectGroup){ - - if(providerGroup != null) { - map.put("providerType", providerGroup.getProviderType()); - map.put("providerName", providerGroup.getName()); - map.put("providerAbbrev", providerGroup.getAbbreviation()); - } - else{ - map.put("providerType", ""); - map.put("providerName", ""); - map.put("providerAbbrev", ""); - } - if(accessGroup != null){ - map.put("modelAccessibility", accessGroup.getAccessibility()); - map.put("accessModalities", accessGroup.getAccessModalities()); - } - else{ - map.put("modelAccessibility", ""); - map.put("accessModalities", ""); - } - - if(projectGroup != null){ - map.put("projectName", projectGroup.getName()); + exportMetadata(providerSheets,templates, dataSource, isHarmonized, exportProviderDir); + exportSamplePlatform(templates, dataSource, exportProviderDir); + exportAllOmicSheets(templates, dataSource, exportProviderDir); + + } catch(IOException e) { + log.error("IO error while exporting data for {} \n {}",dataSource.getAbbreviation(), e.toString()); + } + } + + public void exportSamplePlatform(ExporterTemplates templates, Group group, String exportProviderDir) throws IOException { + List<List<String>> samplePlatform = extractionServices.extractSamplePlatform(group); + XSSFWorkbook samplePlatformTemplate = templates.getTemplate(TSV.templateNames.sampleplatform_template.name()); + String samplePlatformURI = String.format("%s/%s_sampleplatform.xlsx", exportProviderDir, group.getAbbreviation()); + saveSamplePlatformToXlsx(samplePlatformTemplate, samplePlatform, samplePlatformURI); + } + + public void exportMetadata(MetadataSheets providerSheets, ExporterTemplates templates, Group dataSource, boolean isHarmonized, String exportProviderDir) throws IOException { + extractionServices.extractMetadata(dataSource, providerSheets, isHarmonized); + saveMetadataToXlsx(providerSheets, templates, exportProviderDir, dataSource); + } + + private void saveMetadataToXlsx(MetadataSheets providerData, ExporterTemplates templates, String exportProviderDir, Group dataSource) throws IOException { + XSSFWorkbook metadataTemplate = templates.getTemplate(TSV.templateNames.metadata_template.name()); + int sheetNumber = 0; + for(TSV.metadataSheetNames sheetName: TSV.metadataSheetNames.values()){ + writerUtilities.updateXlsxSheetWithData(metadataTemplate.getSheetAt(sheetNumber), + providerData.get(sheetName.name()), 6, 2); + sheetNumber++; + } + if(allMetadataSheetsHaveData(providerData)) { + String metadataFileURI = String.format("%s/%s_metadata.xlsx", exportProviderDir, dataSource.getAbbreviation()); + writerUtilities.writXlsxFromWorkbook(metadataTemplate, metadataFileURI); + } else { log.error("Empty or Null metadata sheet. Skipping export of Metadata."); } + } + + private void saveSamplePlatformToXlsx(XSSFWorkbook samplePlatformTemplate, List<List<String>> samplePlatform, String samplePlatformURI) throws IOException { + writerUtilities.updateXlsxSheetWithData(samplePlatformTemplate.getSheetAt(0), + samplePlatform, 6, 1); + if(!samplePlatform.isEmpty()){ + writerUtilities.writXlsxFromWorkbook(samplePlatformTemplate, samplePlatformURI); + } + } + + private void exportAllOmicSheets(ExporterTemplates templates, Group dataSource, String exportProviderDir) throws IOException { + XSSFWorkbook mutationTemplate = templates.getTemplate(TSV.templateNames.mutation_template.name()); + XSSFWorkbook cnaTemplate = templates.getTemplate(TSV.templateNames.cna_template.name()); + XSSFWorkbook cytoTemplate = templates.getTemplate(TSV.templateNames.cytogenetics_template.name()); + XSSFWorkbook exprTemplate = templates.getTemplate(TSV.templateNames.expression_template.name()); + XSSFWorkbook dosingTemplate = templates.getTemplate(TSV.templateNames.drugdosing_template.name()); + XSSFWorkbook treatmentTemplate = templates.getTemplate(TSV.templateNames.patienttreatment_template.name()); + String mut = TSV.molecular_characterisation_type.mut.name(); + String cna = TSV.molecular_characterisation_type.cna.name(); + String expression = TSV.molecular_characterisation_type.expression.name(); + String cyto = TSV.molecular_characterisation_type.cyto.name(); + String dosing = "drug"; + String treatment = "patientTreatment"; + Path mutExportURI = Paths.get(String.format("%s/%s/%s_%s.tsv",exportProviderDir, mut, dataSource.getAbbreviation(), mut)); + Path cnaExportURI = Paths.get(String.format( "%s/%s/%s_%s.tsv",exportProviderDir, cna, dataSource.getAbbreviation(), cna)); + Path expressionExportURI = Paths.get(String.format("%s/%s/%s_%s.tsv", exportProviderDir, expression, dataSource.getAbbreviation() ,expression)); + Path cytoExportURI = Paths.get(String.format("%s/%s/%s_%s.tsv",exportProviderDir,cyto, dataSource.getAbbreviation() , cyto)); + Path dosingExportURI = Paths.get(String.format("%s/%s/%s_%s.tsv", exportProviderDir, dosing, dataSource.getAbbreviation(), dosing)); + Path treatmentExportURI = Paths.get(String.format("%s/%s/%s_%s.tsv", exportProviderDir, treatment, dataSource.getAbbreviation(), treatment)); + extractAndSaveOmicByBatch(TSV.molecular_characterisation_type.mut.mcType ,mutationTemplate, mutExportURI,dataSource); + extractAndSaveOmicByBatch(TSV.molecular_characterisation_type.cna.mcType ,cnaTemplate, cnaExportURI, dataSource); + extractAndSaveOmicByBatch(TSV.molecular_characterisation_type.cyto.mcType ,cytoTemplate, cytoExportURI, dataSource); + extractAndSaveOmicByBatch(TSV.molecular_characterisation_type.expression.mcType ,exprTemplate, expressionExportURI,dataSource); + extractAndSaveOmicByBatch(dosing, dosingTemplate, dosingExportURI, dataSource); + extractAndSaveOmicByBatch(treatment, treatmentTemplate, treatmentExportURI, dataSource); + } + + public void extractAndSaveOmicByBatch(String molecularType, XSSFWorkbook template, Path exportURI, Group dataSource) throws IOException { + String parentDirectory = exportURI.getParent().toString(); + String fileURI = exportURI.toString(); + Sheet templateSheet = template.getSheetAt(0); + List<ModelCreation> models; + models = getModelsByMolecularTypeAndDataSource(molecularType, dataSource); + if(!models.isEmpty()) { + writerUtilities.createExportDirectories(parentDirectory); + writerUtilities.saveHeadersToTsv(templateSheet, exportURI.toString()); + List<List<String>> modelsOmicData = new ArrayList<>(); + int counter = 0; + for (ModelCreation model : models) { + modelsOmicData.addAll(extractionServices.extractModelsOmicData(model, molecularType)); + if (counter % 10 == 0) { + writerUtilities.appendDataToOmicTsvFile(modelsOmicData, fileURI); + modelsOmicData.clear(); + } + counter++; + } + if (!modelsOmicData.isEmpty()) { + writerUtilities.appendDataToOmicTsvFile(modelsOmicData, fileURI); + modelsOmicData.clear(); + } + } + } + + List<ModelCreation> getModelsByMolecularTypeAndDataSource(String molecularType, Group dataSource) { + List<ModelCreation> models; + if (molecularType.equals("drug")) { + models = dataImportService.findModelsWithTreatmentSummaryByDS(dataSource.getAbbreviation()); + } else if(molecularType.equals("patientTreatment")) { + models = dataImportService.findModelFromPatienSnapshotWithTreatmentSummaryByDS(dataSource.getAbbreviation()); } else { - map.put("projectName", ""); - } - } - - private void getExternalUrlData(LinkedHashMap<String, String> map, Collection<ExternalUrl> urls){ - - map.put("contactEmail", ""); - map.put("contactName", ""); - map.put("contactLink", ""); - map.put("modelLink", ""); - - if(urls != null){ - - for(ExternalUrl ex: urls) { - - if (ex.getType().equals("contact")) { - - if (ex.getUrl() != null && ex.getUrl().contains("@")) { - map.put("contactEmail", ex.getUrl()); - } else { - map.put("contactLink", ex.getUrl()); - } - } else if (ex.getType().equals("source") && ex.getUrl() != null) { - map.put("modelLink", ex.getUrl()); - } - } - } - } - - private void addEntryToSpecimenMap( - Map<String, ModelDetails> specimenMap, - HostStrain hostStrain, - String engraftmentSite, - String engraftmentType, - String engraftmentMaterial, - String engraftmentMaterialStatus, - String passage){ - - String specimenMapKey = String.join( - hostStrain.getName(), - hostStrain.getSymbol(), - engraftmentSite, - engraftmentType, - engraftmentMaterial, - engraftmentMaterialStatus); - - if(specimenMap.containsKey(specimenMapKey)){ - specimenMap.get(specimenMapKey).getPassages().add(passage); - } - else{ - - ModelDetails md = new ModelDetails( - hostStrain.getName(), - hostStrain.getSymbol(), - engraftmentSite, - engraftmentType, - engraftmentMaterial, - engraftmentMaterialStatus, - passage); - specimenMap.put(specimenMapKey, md); - } - } - - private void addPatientMolcharDataToSamplePlatform(ModelCreation model){ - - //get the patient sample related molchars first - if(model.getSample() != null && model.getSample().getMolecularCharacterizations() != null){ - - for(MolecularCharacterization mc : model.getSample().getMolecularCharacterizations()){ - - List<String> dataRow = new ArrayList<>(); - - dataRow.add(""); - dataRow.add(model.getSample().getSourceSampleId()); - dataRow.add(patientOrigin); - dataRow.add("NA"); - dataRow.add(""); - dataRow.add(model.getSourcePdxId()); - dataRow.add(""); - dataRow.add(""); - - dataRow.add(mc.getType()); - dataRow.add(mc.getPlatform().getName()); - dataRow.add(mc.getTechnology()); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(mc.getPlatform().getUrl()); - - samplePlatformDescriptionSheetDataExport.add(dataRow); - } - } - } - - private void addXenoMolcharDataToSamplePlatform(ModelCreation model){ - - if(model.getSpecimens() != null){ - - for(Specimen sp : model.getSpecimens()){ - - String passage = sp.getPassage(); - - String hostStrainName = ""; - String hostStrainNomenclature = ""; - - if(sp.getHostStrain() != null){ - hostStrainName = getHostStrainName(sp); - hostStrainNomenclature = getHostStrainNomenclature(sp); - } - - - Sample sample = sp.getSample(); - - if(sample != null && sample.getMolecularCharacterizations() != null && !sample.getMolecularCharacterizations().isEmpty()){ - - for(MolecularCharacterization mc : sample.getMolecularCharacterizations()) { - - List<String> dataRow = new ArrayList<>(); - - dataRow.add(""); - dataRow.add(sample.getSourceSampleId()); - dataRow.add("xenograft"); - dataRow.add(passage); - dataRow.add(""); - dataRow.add(model.getSourcePdxId()); - dataRow.add(hostStrainName); - dataRow.add(hostStrainNomenclature); - dataRow.add(mc.getType()); - dataRow.add(mc.getPlatform().getName()); - dataRow.add(mc.getTechnology()); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(""); - dataRow.add(mc.getPlatform().getUrl()); - - samplePlatformDescriptionSheetDataExport.add(dataRow); - } - } - } + models = dataImportService.findModelsWithMolecularDataByDSAndMolcharType(dataSource.getAbbreviation(), molecularType); } - + return models; } - private void initPatientGenomicData(ModelCreation model, List<List<String>> sheetData){ - if(model.getSample() != null && model.getSample().getMolecularCharacterizations() != null){ - - String sampleId = model.getSample().getSourceSampleId(); - - for(MolecularCharacterization mc : model.getSample().getMolecularCharacterizations()){ - - insertOmicDataToSheet(model, sampleId, patientOrigin, mc.getType(), null, mc, sheetData); + private boolean allMetadataSheetsHaveData(MetadataSheets providerData){ + for(TSV.metadataSheetNames sheetName: TSV.metadataSheetNames.values()){ + if (providerData.get(sheetName.name()) == null || providerData.get(sheetName.name()).isEmpty() ) { + log.error("Metadata sheet {} was not found. Skipping metadata export", sheetName.name()); + return false; } - } else { - log.error("No molecular data on patient sample found for model {} \n", model.getSourcePdxId()); } + return true; } - private void initXenoGenomicData(ModelCreation model, List<List<String>> sheetData){ - - //then look for xenograft molchars - if(model.getSpecimens()!= null){ - - for(Specimen sp : model.getSpecimens()){ - - if(sp.getSample() != null && sp.getSample().getMolecularCharacterizations() != null){ - - String sampleId = sp.getSample().getSourceSampleId(); - - for(MolecularCharacterization mc: sp.getSample().getMolecularCharacterizations()){ - - insertOmicDataToSheet(model, sampleId,"xenograft", mc.getType(), sp, mc, sheetData); - } - } - } - } else log.error("No specimens found for model {}", model.getId()); - } - - - private XSSFWorkbook getWorkbook(String templatePath) { - - File file = new File(templatePath); - log.debug("Loading template {}", templatePath); - if (!file.exists()) { - log.error("Template not found {}", templatePath); - return null; - } - - - try (FileInputStream fileInputStream = new FileInputStream(file)) { - - return new XSSFWorkbook(fileInputStream); - - } catch (IOException e) { - log.error("There was a problem accessing the file: {}", file, e); - } - return null; - } - - private String getHostStrainName(Specimen sp){ - - return sp.getHostStrain().getName() == null?"":sp.getHostStrain().getName(); - } - - private String getHostStrainNomenclature(Specimen sp){ - return sp.getHostStrain().getSymbol() == null?"":sp.getHostStrain().getSymbol(); - } - - public List<List<String>> getPatientSheetDataExport() { - return patientSheetDataExport; - } - - public List<List<String>> getPatientTumorSheetDataExport() { - return patientTumorSheetDataExport; - } - - public List<List<String>> getPatientTreatmentSheetDataExport() { - return patientTreatmentSheetDataExport; - } - - public List<List<String>> getPdxModelSheetDataExport() { - return pdxModelSheetDataExport; - } - - public List<List<String>> getPdxModelValidationSheetDataExport() { - return pdxModelValidationSheetDataExport; - } - - public List<List<String>> getSamplePlatformDescriptionSheetDataExport() { - return samplePlatformDescriptionSheetDataExport; - } - - public List<List<String>> getSharingAndContactSheetDataExport() { - return sharingAndContactSheetDataExport; - } - - public List<List<String>> getCytogeneticsSheetDataExport() { - return cytogeneticsSheetDataExport; - } - - public List<List<String>> getLoaderRelatedDataSheetDataExport() { - return loaderRelatedDataSheetDataExport; - } - - public List<List<String>> getDrugDosingSheetDataExport() { - return drugDosingSheetDataExport; - } - - public void setMutationSheetDataExport(List<List<String>> mutationSheetDataExport) { - this.mutationSheetDataExport = mutationSheetDataExport; - } - - public List<List<String>> getMutationSheetDataExport() { - return mutationSheetDataExport; - } - - public List<List<String>> getCnaSheetDataExport() { - return cnaSheetDataExport; - } - - public void setCnaSheetDataExport(List<List<String>> cnaSheetDataExport) { - this.cnaSheetDataExport = cnaSheetDataExport; - } - - public void setPatientSheetDataExport(List<List<String>> patientSheetDataExport) { - this.patientSheetDataExport = patientSheetDataExport; - } - - public void setPatientTumorSheetDataExport(List<List<String>> patientTumorSheetDataExport) { - this.patientTumorSheetDataExport = patientTumorSheetDataExport; - } - - public void setPatientTreatmentSheetDataExport(List<List<String>> patientTreatmentSheetDataExport) { - this.patientTreatmentSheetDataExport = patientTreatmentSheetDataExport; - } - - public void setPdxModelSheetDataExport(List<List<String>> pdxModelSheetDataExport) { - this.pdxModelSheetDataExport = pdxModelSheetDataExport; - } - - public void setPdxModelValidationSheetDataExport(List<List<String>> pdxModelValidationSheetDataExport) { - this.pdxModelValidationSheetDataExport = pdxModelValidationSheetDataExport; - } - - public void setSamplePlatformDescriptionSheetDataExport(List<List<String>> samplePlatformDescriptionSheetDataExport) { - this.samplePlatformDescriptionSheetDataExport = samplePlatformDescriptionSheetDataExport; - } - - public void setSharingAndContactSheetDataExport(List<List<String>> sharingAndContactSheetDataExport) { - this.sharingAndContactSheetDataExport = sharingAndContactSheetDataExport; - } - - public void setCytogeneticsSheetDataExport(List<List<String>> cytogeneticsSheetDataExport) { - this.cytogeneticsSheetDataExport = cytogeneticsSheetDataExport; - } - - public void setLoaderRelatedDataSheetDataExport(List<List<String>> loaderRelatedDataSheetDataExport) { - this.loaderRelatedDataSheetDataExport = loaderRelatedDataSheetDataExport; - } - - public void setDrugDosingSheetDataExport(List<List<String>> drugDosingSheetDataExport) { - this.drugDosingSheetDataExport = drugDosingSheetDataExport; - } - - } diff --git a/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExtractionServices.java b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExtractionServices.java new file mode 100644 index 0000000000000000000000000000000000000000..fad1c53bc914bc4815c399e0d2f5a69aae0d0a61 --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataExtractionServices.java @@ -0,0 +1,788 @@ +package org.pdxfinder.dataexport; + +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.*; +import org.pdxfinder.services.DataImportService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +/* + * Created by csaba on 02/10/2019. + */ +@Service +public class UniversalDataExtractionServices { + + private static final Logger log = LoggerFactory.getLogger(UniversalDataExtractionServices.class); + + private DataImportService dataImportService; + + public static final String MODEL_ID = "modelId"; + public static final String PROVIDER_TYPE = "providerType"; + public static final String MODEL_ACCESSIBILITY = "modelAccessibility"; + public static final String ACCESS_MODALITIES = "accessModalities"; + public static final String CONTACT_EMAIL = "contactEmail"; + public static final String CONTACT_NAME = "contactName"; + public static final String CONTACT_LINK = "contactLink"; + public static final String MODEL_LINK = "modelLink"; + public static final String PROVIDER_NAME = "providerName"; + public static final String PROVIDER_ABBREV = "providerAbbrev"; + public static final String PROJECT_NAME = "projectName"; + private static final String NOT_SPECIFIED = "Not Specified"; + private static final String PATIENT_ORIGIN = "patient"; + private static final String MODEL_ORIGIN = "xenograft"; + + static final String EMPTY = ""; + + @Autowired + public UniversalDataExtractionServices(DataImportService dataImportService) { + this.dataImportService = dataImportService; + } + + public MetadataSheets extractMetadata(Group group, MetadataSheets sheets, boolean isHarmonized){ + sheets.set(TSV.metadataSheetNames.checklist.name(), extractChecklist()); + sheets.set(TSV.metadataSheetNames.patient.name(), extractPatientSheet(group)); + sheets.set(TSV.metadataSheetNames.sample.name(), extractSampleSheet(group, isHarmonized)); + sheets.set(TSV.metadataSheetNames.model.name(), extractModelDetails(group)); + sheets.set(TSV.metadataSheetNames.model_validation.name(), extractModelValidations(group)); + sheets.set(TSV.metadataSheetNames.sharing.name(), extractSharingAndContact(group)); + sheets.set(TSV.metadataSheetNames.loader.name(), extractLoaderRelatedData(group)); + return sheets; + } + + public List<List<String>> extractChecklist(){ + List<List<String>> checklist = new ArrayList<>(); + List<String> deprecatedMessageRow = new ArrayList<>(); + deprecatedMessageRow.add(EMPTY); + checklist.add(deprecatedMessageRow); + return checklist; + } + + public List<List<String>> extractPatientSheet(Group group) { + List<Patient> patients = dataImportService.findPatientsByGroup(group); + List<List<String>> patientSheetDataExport = new ArrayList<>(); + for (Patient patient : patients) { + + List<String> dataRow = new ArrayList<>(); + + String patientId = patient.getExternalId(); + String sex = patient.getSex(); + String cancerHistory = patient.getCancerRelevantHistory(); + String ethnicity = patient.getEthnicity(); + String ethnicityAssessment = patient.getEthnicityAssessment(); + String firstDiagnosis = patient.getFirstDiagnosis(); + String ageAtFirstDiagnosis = patient.getAgeAtFirstDiagnosis(); + + dataRow.add(patientId); + dataRow.add(sex); + dataRow.add(cancerHistory); + dataRow.add(ethnicity); + dataRow.add(ethnicityAssessment); + dataRow.add(firstDiagnosis); + dataRow.add(ageAtFirstDiagnosis); + + patientSheetDataExport.add(dataRow); + } + return patientSheetDataExport; + } + + public List<List<String>> extractSampleSheet(Group group, boolean isHarmonized){ + List<Patient> patients = dataImportService.findPatientTumorAtCollectionDataByDS(group); + List<List<String>> sampleSheetDataExport = new ArrayList<>(); + for(Patient patient : patients){ + String patientId = patient.getExternalId(); + for(PatientSnapshot patientSnapshot : patient.getSnapshots()){ + for(Sample sample : patientSnapshot.getSamples()){ + + List<String> dataRow = new ArrayList<>(); + String sampleId = sample.getSourceSampleId(); + String collectionDate = patientSnapshot.getDateAtCollection(); + String collectionEvent = patientSnapshot.getCollectionEvent(); + String elapsedTime = patientSnapshot.getElapsedTime(); + String ageAtCollection = patientSnapshot.getAgeAtCollection(); + String diagnosis = getSampleUnharmonizedDiagnosis(sample); + String tumorType = sample.getType().getName(); + String primarySite = sample.getOriginTissue().getName(); + String collectionSite = sample.getSampleSite().getName(); + String stage = sample.getStage(); + String stageClassification = sample.getStageClassification(); + String grade = sample.getGrade(); + String gradeClassification = sample.getGradeClassification(); + String virologyStatus = patientSnapshot.getVirologyStatus(); + String isPatientTreatmentInfoAvailable = EMPTY; + String treatmentNaive = patientSnapshot.getTreatmentNaive(); + String isPatientTreated = EMPTY; + String wasPatientTreated = EMPTY; + String modelId = getModelIdBySample(sample); + + dataRow.add(patientId); + dataRow.add(sampleId); + dataRow.add(collectionDate); + dataRow.add(collectionEvent); + dataRow.add(elapsedTime); + dataRow.add(ageAtCollection); + dataRow.add(diagnosis); + addHarmonizedDiagnosis(dataRow, sample, isHarmonized); + dataRow.add(tumorType); + dataRow.add(primarySite); + dataRow.add(collectionSite); + dataRow.add(stage); + dataRow.add(stageClassification); + dataRow.add(grade); + dataRow.add(gradeClassification); + dataRow.add(virologyStatus); + dataRow.add(isPatientTreatmentInfoAvailable); + dataRow.add(treatmentNaive); + dataRow.add(isPatientTreated); + dataRow.add(wasPatientTreated); + dataRow.add(modelId); + sampleSheetDataExport.add(dataRow); + } + } + } + return sampleSheetDataExport; + } + + private void addHarmonizedDiagnosis(List<String> dataRow, Sample sample, boolean isHarmonized){ + if(isHarmonized){ + String harmonizedDiagnosis = getHarmonizedDiagnosis(sample); + dataRow.add(harmonizedDiagnosis); + } + } + + private String getHarmonizedDiagnosis(Sample sample){ + String diagnosis = EMPTY; + try{ + diagnosis = sample.getSampleToOntologyRelationship().getOntologyTerm().getLabel(); + } catch (NullPointerException e){ + log.warn("Sample {} was not mapped to an ontology term", sample.getSourceSampleId()); + } + return diagnosis; + } + + private String getSampleUnharmonizedDiagnosis(Sample sample) { + return sample.getDiagnosis(); + } + + private String getModelIdBySample(Sample sample){ + String modelId = EMPTY; + try { + modelId = dataImportService.findModelBySample(sample).getSourcePdxId(); + } + catch (Exception e){ + log.error("Could not find Model associated with Sample: {} ", sample.getSourceSampleId()); + } + return modelId; + } + + public List<List<String>> extractModelDetails(Group group){ + + List<ModelCreation> models = dataImportService.findModelsWithSpecimensAndQAByDS(group.getAbbreviation()); + List<List<String>> modelSheetDataExport = new ArrayList<>(); + for(ModelCreation model : models){ + Map<String, ModelDetails> specimenMap = new HashMap<>(); + for(Specimen specimen : model.getSpecimens()){ + + String passage = specimen.getPassage(); + String engraftmentSite = getEngraftmentSite(specimen); + String engraftmentType = getEngraftmentType(specimen); + String[] engraftmentMaterialInfo = getEngraftmentMaterialInfo(specimen); + String engraftmentMaterial = engraftmentMaterialInfo[0]; + String engraftmentMaterialStatus = engraftmentMaterialInfo[1]; + + addEntryToSpecimenMap( + specimenMap, + specimen.getHostStrain(), + engraftmentSite, + engraftmentType, + engraftmentMaterial, + engraftmentMaterialStatus, + passage); + } + modelSheetDataExport.addAll(insertModelSheetDataFromSpecimenMap(specimenMap, model)); + } + return modelSheetDataExport; + } + + private List<List<String>> insertModelSheetDataFromSpecimenMap(Map<String, ModelDetails> specimenMap, ModelCreation model){ + List<List<String>> modelSheetDataExport = new ArrayList<>(); + String modelId = model.getSourcePdxId(); + String pubmedIDs = getPubmedIDs(model); + + for(Map.Entry<String, ModelDetails> entry : specimenMap.entrySet()){ + + ModelDetails md = entry.getValue(); + List<String> dataRow = new ArrayList<>(); + + dataRow.add(modelId); + dataRow.add(md.getHostStrainName()); + dataRow.add(md.getHostStrainNomenclature()); + dataRow.add(md.getEngraftmentSite()); + dataRow.add(md.getEngraftmentType()); + dataRow.add(md.getEngraftmentMaterial()); + dataRow.add(md.getEngraftmentMaterialStatus()); + dataRow.add(md.getSortedPassages()); + dataRow.add(pubmedIDs); + + modelSheetDataExport.add(dataRow); + } + return modelSheetDataExport; + } + + private String[] getEngraftmentMaterialInfo(Specimen specimen){ + String[] engraftmentInfo = {NOT_SPECIFIED, NOT_SPECIFIED}; + if(Objects.nonNull(specimen.getEngraftmentMaterial())){ + engraftmentInfo[0] = specimen.getEngraftmentMaterial().getName(); + engraftmentInfo[1] = specimen.getEngraftmentMaterial().getState(); + } + return engraftmentInfo; + } + + private String getEngraftmentSite(Specimen specimen){ + String engraftmentSite = NOT_SPECIFIED; + if (Objects.nonNull(specimen.getEngraftmentSite())){ + engraftmentSite = specimen.getEngraftmentSite().getName(); + } + return engraftmentSite; + } + + private String getEngraftmentType(Specimen specimen){ + String engraftmentType = NOT_SPECIFIED; + if (Objects.nonNull(specimen.getEngraftmentType())){ + engraftmentType = specimen.getEngraftmentType().getName(); + } + return engraftmentType; + } + + public List<List<String>> extractModelValidations(Group group){ + List<List<String>> modelValidationSheetDataExport = new ArrayList<>(); + List<ModelCreation> models = dataImportService.findModelsWithSpecimensAndQAByDS(group.getAbbreviation()); + + for(ModelCreation model : models){ + + if(model != null && model.getQualityAssurance() != null) { + + String modelId = model.getSourcePdxId(); + + for (QualityAssurance qa : model.getQualityAssurance()) { + + List<String> dataRow = new ArrayList<>(); + String validationTechnique = qa.getTechnology(); + String validationDescription = qa.getDescription(); + String passages = qa.getPassages(); + String nomenclature = qa.getValidationHostStrain(); + dataRow.add(modelId); + dataRow.add(validationTechnique); + dataRow.add(validationDescription); + dataRow.add(passages); + dataRow.add(nomenclature); + modelValidationSheetDataExport.add(dataRow); + } + } + } + return modelValidationSheetDataExport; + } + + public List<List<String>> extractSharingAndContact(Group group){ + List<ModelCreation> models = dataImportService.findModelsWithSharingAndContactByDS(group.getAbbreviation()); + List<List<String>> sharingAndContactSheetDataExport = new ArrayList<>(); + + for(ModelCreation model : models){ + + LinkedHashMap<String, String> sharingAndContactRow = new LinkedHashMap<>(); + sharingAndContactRow.put(MODEL_ID, model.getSourcePdxId()); + Group providerGroup = getGroupByType(model, "Provider"); + Group accessGroup = getGroupByType(model, "Accessibility"); + Group projectGroup = getGroupByType(model, "Project"); + getGroupData(sharingAndContactRow, providerGroup, accessGroup, projectGroup); + getExternalUrlData(sharingAndContactRow, model.getExternalUrls()); + + List<String> dataRow = new ArrayList<>(); + dataRow.add(sharingAndContactRow.get(MODEL_ID)); + dataRow.add(sharingAndContactRow.get(PROVIDER_TYPE)); + dataRow.add(sharingAndContactRow.get(MODEL_ACCESSIBILITY)); + dataRow.add(sharingAndContactRow.get(ACCESS_MODALITIES)); + dataRow.add(sharingAndContactRow.get(CONTACT_EMAIL)); + dataRow.add(sharingAndContactRow.get(CONTACT_NAME)); + dataRow.add(sharingAndContactRow.get(CONTACT_LINK)); + dataRow.add(sharingAndContactRow.get(MODEL_LINK)); + dataRow.add(sharingAndContactRow.get(PROVIDER_NAME)); + dataRow.add(sharingAndContactRow.get(PROVIDER_ABBREV)); + dataRow.add(sharingAndContactRow.get(PROJECT_NAME)); + sharingAndContactSheetDataExport.add(dataRow); + } + return sharingAndContactSheetDataExport; + } + + public List<List<String>> extractLoaderRelatedData(Group group){ + List<List<String>> loaderRelatedDataSheetDataExport = new ArrayList<>(); + List<String> dataRow = new ArrayList<>(); + dataRow.add(group.getName()); + dataRow.add(group.getAbbreviation()); + dataRow.add(group.getUrl()); + loaderRelatedDataSheetDataExport.add(dataRow); + return loaderRelatedDataSheetDataExport; + } + + public List<List<String>> extractSamplePlatform(Group group){ + List<List<String>> samplePlatformDescriptionSheetDataExport = new ArrayList<>(); + List<ModelCreation> models = dataImportService.findModelXenograftPlatformSampleByDS(group.getAbbreviation()); + for(ModelCreation model : models){ + samplePlatformDescriptionSheetDataExport.addAll(addPatientMolcharDataToSamplePlatform(model)); + samplePlatformDescriptionSheetDataExport.addAll(addXenoMolcharDataToSamplePlatform(model)); + } + return samplePlatformDescriptionSheetDataExport; + } + + public List<List<String>> extractModelsOmicData(ModelCreation model, String molcharType){ + List<List<String>> modelsOmicExportSheet = new ArrayList<>(); + if(model != null) { + String modelId = model.getSourcePdxId(); + log.info("ModelId {}: Starting extraction of omic {} data",modelId, molcharType); + + if(molcharType.equals("drug")){ + modelsOmicExportSheet.addAll(extractDrugDosing(model)); + } + else if(molcharType.equals("patientTreatment")){ + modelsOmicExportSheet.addAll(extractPatientTreatment(model)); + } + else { + modelsOmicExportSheet.addAll(extractPatientSampleOmicData(model, molcharType)); + modelsOmicExportSheet.addAll(extractXenoSampleOmicDataForEachSpecimen(model, molcharType)); + } + } + return modelsOmicExportSheet; + } + + private List<List<String>> extractDrugDosing(ModelCreation model){ + List<List<String>> drugDosingTable =new ArrayList<>(); + if(model.getTreatmentSummary() != null && model.getTreatmentSummary().getTreatmentProtocols() != null) { + String modelId = model.getSourcePdxId(); + List<TreatmentProtocol> treatmentProtocols = model.getTreatmentSummary().getTreatmentProtocols(); + for(TreatmentProtocol treatmentProtocol: treatmentProtocols){ + List<String> drugDosingRow = new ArrayList<>(); + List<TreatmentComponent> treatmentComponents = treatmentProtocol.getComponents(); + Response response = treatmentProtocol.getResponse(); + String description = EMPTY; + String classification = EMPTY; + if(response != null){ + description = response.getDescription(); + classification = response.getDescriptionClassification(); + } + String treatmentName = treatmentComponents.stream() + .map(x -> x.getTreatment().getName()) + .collect(Collectors.joining(" + ")); + String dose = treatmentComponents.get(0).getDose(); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingRow.add(modelId); + drugDosingRow.add(EMPTY); + drugDosingRow.add(treatmentName); + drugDosingRow.add(EMPTY); + drugDosingRow.add(dose); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingRow.add(description); + drugDosingRow.add(classification); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingRow.add(EMPTY); + drugDosingTable.add(drugDosingRow); + } + } + return drugDosingTable; + } + + private List<List<String>> extractPatientTreatment (ModelCreation model) { + List<List<String>> patientTreatmentTable =new ArrayList<>(); + if (model.getSample() != null && model.getSample().getPatientSnapshot() != null) { + PatientSnapshot patientSnapshot = model.getSample().getPatientSnapshot(); + if (patientSnapshot.getTreatmentSummary() != null && patientSnapshot.getTreatmentSummary().getTreatmentProtocols() != null) { + String patientId = patientSnapshot.getPatient().getExternalId(); + List<TreatmentProtocol> treatmentProtocols = patientSnapshot.getTreatmentSummary().getTreatmentProtocols(); + for (TreatmentProtocol treatmentProtocol : treatmentProtocols) { + List<String> patientTreatmentRow = new ArrayList<>(); + List<TreatmentComponent> treatmentComponents = treatmentProtocol.getComponents(); + Response response = treatmentProtocol.getResponse(); + String treatmentName = treatmentComponents.stream() + .map(x -> x.getTreatment().getName()) + .collect(Collectors.joining(" + ")); + String dose = treatmentComponents.get(0).getDose(); + patientTreatmentRow.add(patientId); + patientTreatmentRow.add(treatmentName); + patientTreatmentRow.add(dose); + patientTreatmentRow.add(EMPTY); + patientTreatmentRow.add(EMPTY); + patientTreatmentRow.add(EMPTY); + patientTreatmentRow.add(EMPTY); + patientTreatmentRow.add(response.getDescription()); + patientTreatmentRow.add(response.getDescriptionClassification()); + patientTreatmentRow.add(EMPTY); + patientTreatmentTable.add(patientTreatmentRow); + } + } + } + return patientTreatmentTable; + } + private List<List<String>> parseOmicDataToSheet( + ModelCreation model, + String sampleId, + String sampleOrigin, + String molcharType, + Specimen specimen, + MolecularCharacterization mc){ + + List<List<String>> sheetData = new ArrayList<>(); + for(MarkerAssociation ma: mc.getMarkerAssociations()) { + List<MolecularData> molecularData; + try { + molecularData = ma.decodeMolecularData(); + } catch (Exception e) { + log.error("Error decoding molecular Data on sample Id {} " + + "for molecularCharacterization type {}", sampleId, mc.getType()); + molecularData = new ArrayList<>(); + } + for (MolecularData md : molecularData) { + List<String> rowData = new ArrayList<>(); + rowData.add(model.getSourcePdxId()); + rowData.add(sampleId); + rowData.add(sampleOrigin); + rowData.add(getHostStrainNameSymbol(specimen)); + rowData.add(getPassage(sampleOrigin, specimen)); + switch (molcharType) { + case "mutation": + rowData.add(md.getMarker()); + rowData.add(md.getBiotype()); + rowData.add(md.getCodingSequenceChange()); + rowData.add(md.getVariantClass()); + rowData.add(md.getCodonChange()); + rowData.add(md.getAminoAcidChange()); + rowData.add(md.getConsequence()); + rowData.add(md.getFunctionalPrediction()); + rowData.add(md.getReadDepth()); + rowData.add(md.getAlleleFrequency()); + rowData.add(md.getChromosome()); + rowData.add(md.getSeqStartPosition()); + rowData.add(md.getRefAllele()); + rowData.add(md.getAltAllele()); + rowData.add(md.getUcscGeneId()); + rowData.add(md.getNcbiGeneId()); + rowData.add(md.getNcbiTranscriptId()); + rowData.add(md.getEnsemblGeneId()); + rowData.add(md.getEnsemblTranscriptId()); + rowData.add(md.getExistingVariations()); + rowData.add(md.getGenomeAssembly()); + rowData.add(mc.getPlatform().getName()); + break; + case "copy number alteration": + rowData.add(md.getChromosome()); + rowData.add(md.getSeqStartPosition()); + rowData.add(md.getSeqEndPosition()); + rowData.add(md.getMarker()); + rowData.add(md.getUcscGeneId()); + rowData.add(md.getNcbiGeneId()); + rowData.add(md.getEnsemblGeneId()); + rowData.add(md.getCnaLog10RCNA()); + rowData.add(md.getCnaLog2RCNA()); + rowData.add(md.getFold_change()); + rowData.add(md.getCnaCopyNumberStatus()); + rowData.add(md.getCnaGisticValue()); + rowData.add(md.getCnaPicnicValue()); + rowData.add(md.getGenomeAssembly()); + rowData.add(mc.getPlatform().getName()); + break; + case "cytogenetics": + rowData.add(EMPTY); + rowData.add(md.getMarker()); + rowData.add(md.getCytogeneticsResult()); + rowData.add(md.getMarkerStatusComment()); + rowData.add(mc.getPlatform().getName()); + rowData.add(EMPTY); + rowData.add(EMPTY); + break; + case "expression": + rowData.add(md.getChromosome()); + rowData.add(EMPTY); + rowData.add(md.getSeqStartPosition()); + rowData.add(md.getSeqEndPosition()); + rowData.add(md.getMarker()); + rowData.add(EMPTY); + rowData.add(EMPTY); + rowData.add(EMPTY); + rowData.add(md.getRnaSeqCoverage()); + rowData.add(md.getRnaSeqFPKM()); + rowData.add(md.getRnaSeqTPM()); + rowData.add(md.getRnaSeqCount()); + rowData.add(md.getAffyHGEAProbeId()); + rowData.add(md.getAffyHGEAExpressionValue()); + rowData.add(md.getIlluminaHGEAProbeId()); + rowData.add(md.getIlluminaHGEAExpressionValue()); + rowData.add(md.getZscore()); + rowData.add(md.getGenomeAssembly()); + rowData.add(mc.getPlatform().getName()); + break; + default: + throw new IllegalArgumentException("Inappropriate molecular data type passed"); + } + sheetData.add(rowData); + } + } + return sheetData; + } + + private String getHostStrainNameSymbol(Specimen specimen) { + String hostStrainSymbol = EMPTY; + if (specimen != null && specimen.getHostStrain() != null && specimen.getHostStrain().getSymbol() != null) { + hostStrainSymbol = specimen.getHostStrain().getSymbol(); + } + return hostStrainSymbol; + } + + private String getPassage(String sampleOrigin, Specimen specimen) { + return (!sampleOrigin.equals(PATIENT_ORIGIN) && specimen != null) ? specimen.getPassage() : EMPTY ; + } + + private String getPubmedIDs(ModelCreation model){ + StringBuilder pubmedIDs = new StringBuilder(); + if(model.getGroups() != null){ + for(Group g : model.getGroups()){ + if(g.getType().equals("Publication")){ + if(pubmedIDs.length() != 0){ + pubmedIDs.append(","); + } + pubmedIDs.append(g.getPubMedId()); + } + } + } + return pubmedIDs.toString(); + } + + private Group getGroupByType(ModelCreation model, String type){ + if(model.getGroups() != null){ + for(Group g : model.getGroups()){ + if(g.getType().equals(type)){ + return g; + } + } + } + return null; + } + + private void getGroupData(LinkedHashMap<String, String> map, Group providerGroup, Group accessGroup, Group projectGroup){ + + if(providerGroup != null) { + map.put(PROVIDER_TYPE, providerGroup.getProviderType()); + map.put(PROVIDER_NAME, providerGroup.getName()); + map.put(PROVIDER_ABBREV, providerGroup.getAbbreviation()); + } + else{ + map.put(PROVIDER_TYPE, EMPTY); + map.put(PROVIDER_NAME, EMPTY); + map.put(PROVIDER_ABBREV, EMPTY); + } + if(accessGroup != null){ + map.put(MODEL_ACCESSIBILITY, accessGroup.getAccessibility()); + map.put(ACCESS_MODALITIES, accessGroup.getAccessModalities()); + } + else{ + map.put(MODEL_ACCESSIBILITY, EMPTY); + map.put(ACCESS_MODALITIES, EMPTY); + } + + if(projectGroup != null){ + map.put(PROJECT_NAME, projectGroup.getName()); + } + else { + map.put(PROJECT_NAME, EMPTY); + } + } + + private void getExternalUrlData(LinkedHashMap<String, String> map, Collection<ExternalUrl> urls){ + map.put(CONTACT_EMAIL, EMPTY); + map.put(CONTACT_NAME, EMPTY); + map.put(CONTACT_LINK, EMPTY); + map.put(MODEL_LINK, EMPTY); + + if(urls != null){ + for(ExternalUrl ex: urls) { + if (ex.getType().equals("contact")) { + + if (ex.getUrl() != null && ex.getUrl().contains("@")) { + map.put(CONTACT_EMAIL, ex.getUrl()); + } else { + map.put(CONTACT_LINK, ex.getUrl()); + } + } else if (ex.getType().equals("source") && ex.getUrl() != null) { + map.put(MODEL_LINK, ex.getUrl()); + } + } + } + } + + private void addEntryToSpecimenMap( + Map<String, ModelDetails> specimenMap, + HostStrain hostStrain, + String engraftmentSite, + String engraftmentType, + String engraftmentMaterial, + String engraftmentMaterialStatus, + String passage){ + + String specimenMapKey = String.join( + hostStrain.getName(), + hostStrain.getSymbol(), + engraftmentSite, + engraftmentType, + engraftmentMaterial, + engraftmentMaterialStatus); + + if(specimenMap.containsKey(specimenMapKey)){ + specimenMap.get(specimenMapKey).getPassages().add(passage); + } + else{ + ModelDetails md = new ModelDetails( + hostStrain.getName(), + hostStrain.getSymbol(), + engraftmentSite, + engraftmentType, + engraftmentMaterial, + engraftmentMaterialStatus, + passage); + specimenMap.put(specimenMapKey, md); + } + } + + private ArrayList<List<String>> addPatientMolcharDataToSamplePlatform(ModelCreation model){ + ArrayList<List<String>> samplePlatformPatientSheetDataExport = new ArrayList<>(); + if(model.getSample() != null && model.getSample().getMolecularCharacterizations() != null){ + for(MolecularCharacterization mc : model.getSample().getMolecularCharacterizations()){ + List<String> dataRow = new ArrayList<>(); + dataRow.add(EMPTY); + dataRow.add(model.getSample().getSourceSampleId()); + dataRow.add(PATIENT_ORIGIN); + dataRow.add("NA"); + dataRow.add(EMPTY); + dataRow.add(model.getSourcePdxId()); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(mc.getType()); + dataRow.add(mc.getPlatform().getName()); + dataRow.add(mc.getTechnology()); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(mc.getPlatform().getUrl()); + + samplePlatformPatientSheetDataExport.add(dataRow); + } + } + return samplePlatformPatientSheetDataExport; + } + + private List<List<String>> addXenoMolcharDataToSamplePlatform(ModelCreation model){ + ArrayList<List<String>> samplePlatformXenoDataSheetDataExport = new ArrayList<>(); + if(Objects.nonNull(model.getSpecimens())){ + for(Specimen sp : model.getSpecimens()){ + + String passage = sp.getPassage(); + String hostStrainName = getHostStrainName(sp); + String hostStrainNomenclature = getHostStrainNomenclature(sp); + Sample sample = sp.getSample(); + + if(sample != null && sample.getMolecularCharacterizations() != null && !sample.getMolecularCharacterizations().isEmpty()){ + + for(MolecularCharacterization mc : sample.getMolecularCharacterizations()) { + + List<String> dataRow = new ArrayList<>(); + + dataRow.add(EMPTY); + dataRow.add(sample.getSourceSampleId()); + dataRow.add(MODEL_ORIGIN); + dataRow.add(passage); + dataRow.add(EMPTY); + dataRow.add(model.getSourcePdxId()); + dataRow.add(hostStrainName); + dataRow.add(hostStrainNomenclature); + dataRow.add(mc.getType()); + dataRow.add(mc.getPlatform().getName()); + dataRow.add(mc.getTechnology()); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(EMPTY); + dataRow.add(mc.getPlatform().getUrl()); + + samplePlatformXenoDataSheetDataExport.add(dataRow); + } + } + } + } + return samplePlatformXenoDataSheetDataExport; + } + + private List<List<String>> extractPatientSampleOmicData(ModelCreation model, String molcharType){ + List<List<String>> patientOmic = new ArrayList<>(); + if(model.getSample() != null && model.getSample().getMolecularCharacterizations() != null){ + String sampleId = model.getSample().getSourceSampleId(); + + for(MolecularCharacterization mc : model.getSample().getMolecularCharacterizations()){ + if(mc.getType().equals(molcharType)){ + log.info("ModelId {}: Extracting patient sample {} information",model.getSourcePdxId(), sampleId); + patientOmic.addAll(parseOmicDataToSheet(model, sampleId, PATIENT_ORIGIN, mc.getType(), null, mc)); + } + } + } + return patientOmic; + } + + private List<List<String>> extractXenoSampleOmicDataForEachSpecimen(ModelCreation model, String molcharType) { + List<List<String>> xenograftOmic = new ArrayList<>(); + if(model.getSpecimens() != null) { + for (Specimen specimen : model.getSpecimens()) { + if (specimenHasMolecularCharacterizations(specimen)) { + xenograftOmic.addAll( + extractXenoSampleOmicDataForEachMolecularCharacterization(specimen, molcharType, model)); + } + } + if(xenograftOmic.isEmpty()){ + log.error("ModelId {}: Error extracting xenograft information", model.getSourcePdxId()); + } + } + return xenograftOmic; + } + + private List<List<String>> extractXenoSampleOmicDataForEachMolecularCharacterization(Specimen specimen, String molcharType, ModelCreation model){ + List<List<String>> OmicData = new ArrayList<>(); + for (MolecularCharacterization mc : specimen.getSample().getMolecularCharacterizations()) { + if (mc.getType().equals(molcharType)) { + String sampleId = specimen.getSample().getSourceSampleId(); + log.info("ModelId {}: Extracting sample {} information", model.getSourcePdxId(), sampleId); + OmicData.addAll(parseOmicDataToSheet(model, sampleId, + MODEL_ORIGIN, mc.getType(), specimen, mc)); + } + } + return OmicData; + } + + private boolean specimenHasMolecularCharacterizations(Specimen specimen){ + return (specimen.getSample() != null && specimen.getSample().getMolecularCharacterizations() != null); + } + + private String getHostStrainName(Specimen sp){ + return sp.getHostStrain().getName() == null? EMPTY :sp.getHostStrain().getName(); + } + + private String getHostStrainNomenclature(Specimen sp){ + return sp.getHostStrain().getSymbol() == null? EMPTY :sp.getHostStrain().getSymbol(); + } + +} diff --git a/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataWriterServices.java b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataWriterServices.java new file mode 100644 index 0000000000000000000000000000000000000000..b3313bc8482bc40586ebfb7489a29f5a6b993b5b --- /dev/null +++ b/indexer/src/main/java/org/pdxfinder/dataexport/UniversalDataWriterServices.java @@ -0,0 +1,114 @@ +package org.pdxfinder.dataexport; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static java.util.Objects.nonNull; + +@Component +public class UniversalDataWriterServices { + + private static final Logger log = LoggerFactory.getLogger(UniversalDataWriterServices.class); + + public void writXlsxFromWorkbook(XSSFWorkbook dataWorkbook, String fileLocation) throws IOException { + FileOutputStream fileOut = new FileOutputStream(fileLocation); + dataWorkbook.write(fileOut); + fileOut.close(); + } + + public void updateXlsxSheetWithData(Sheet sheet, List<List<String>> data, int startRow, int startColumn) { + if (nonNull(data)) { + for (int i = 0; i < data.size(); i++) { + int rowIndex = startRow + i - 1; + sheet.createRow(rowIndex); + for (int j = 0; j < data.get(i).size(); j++) { + int columnIndex = startColumn + j - 1; + sheet.getRow(rowIndex).createCell(columnIndex); + Cell cell; + try { + cell = sheet.getRow(rowIndex).getCell(columnIndex); + cell.setCellValue(data.get(i).get(j)); + } catch (Exception e) { + log.error("Exception in {} {}:{}", sheet.getSheetName(), rowIndex, columnIndex); + } + } + } + } + } + + public void writeSingleOmicFileToTsv(String exportLocation, Sheet template, + List<List<String>> exportSheet) throws IOException { + createExportDirectories(exportLocation); + saveHeadersToTsv(template, exportLocation); + appendDataToOmicTsvFile(exportSheet, exportLocation); + } + + public void createExportDirectories(String exportFileLocation) throws IOException { + Path directory = Paths.get(exportFileLocation); + Files.createDirectories(directory); + if(!directory.toFile().exists()) { + throw new IOException(String.format("Failed to create file directory at %s", + directory.toAbsolutePath().toString())); + } + } + + public void saveHeadersToTsv(Sheet template, String exportFileLocation) { + try (FileWriter fileWriter = new FileWriter(exportFileLocation)) { + saveHeadersToTsv(template, fileWriter); + } catch (IOException e) { + log.error("IO Error writing headers from {} to {} \n {}", template.getSheetName(), exportFileLocation, e.toString()); + } + } + + public void appendDataToOmicTsvFile(List<List<String>> exportSheet, String exportFileLocation) { + try(FileWriter fileWriter = new FileWriter(exportFileLocation, true)) { + if (exportSheet != null) { + writeDataToTsv(exportSheet, fileWriter); + } + } catch(Exception e) { + log.error("IO Error from reading omic TSV {}",e.toString()); + } + } + + private void saveHeadersToTsv(Sheet xlsxTemplate, FileWriter fileWriter) throws IOException { + for (int j = 0; j < xlsxTemplate.getRow(0).getLastCellNum(); j++) { + Cell cell; + try { + cell = xlsxTemplate.getRow(0).getCell(j); + if(cell != null) { + fileWriter.append(cell.toString()); + fileWriter.append("\t"); + } + } catch (IOException e) { + log.error("IOException in loading export headers"); + } + } + fileWriter.append("\n"); + } + + private void writeDataToTsv(List<List<String>> data, FileWriter fileWriter) throws IOException { + for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { + for (int columnIndex = 0; columnIndex < data.get(rowIndex).size(); columnIndex++) { + try { + fileWriter.append(data.get(rowIndex).get(columnIndex)); + fileWriter.append("\t"); + } catch (IOException e) { + log.error("IOException writing data to TSV on {}:{}", rowIndex, columnIndex); + } + } + fileWriter.append("\n"); + } + } +} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadAdditionalDatasets.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadAdditionalDatasets.java deleted file mode 100644 index a75d9e0f7b35b6da3c96be3ff11fb1a6bf5ea846..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadAdditionalDatasets.java +++ /dev/null @@ -1,278 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.reportmanager.ReportManager; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.dto.NodeSuggestionDTO; -import org.pdxfinder.services.reporting.MarkerLogEntity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Service; - -import java.io.File; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -@Service -@Order(value = 15) -public class LoadAdditionalDatasets implements ApplicationContextAware{ - - @Value("${data-dir}") - private String finderRootDir; - - Logger log = LoggerFactory.getLogger(LoadAdditionalDatasets.class); - - private static ApplicationContext context; - private ReportManager reportManager; - - @Autowired - private DataImportService dataImportService; - - @Autowired - private UtilityService utilityService; - - - public void run() { - - reportManager = (ReportManager) context.getBean("ReportManager"); - - loadAdditionalDatasetForCRL(); - } - - - private void loadAdditionalDatasetForCRL() { - - log.info("Loading additional datasets for CRL."); - - String templateFileStr = finderRootDir+"/data/UPDOG/CRL/template.xlsx"; - String markerTemplateFileStr = finderRootDir + "/data/UPDOG/CRL/cna_tested_markers/list.csv"; - - File markerListFile = new File(markerTemplateFileStr); - File templateFile = new File(templateFileStr); - - Set<Marker> markerSet = new HashSet<>(); - - if(markerListFile.exists() && templateFile.exists()){ - - List<List<String>> markerList = utilityService.serializeCSVToArrayList(markerTemplateFileStr); - - //STEP1: get the marker symbols from the csv file then find the corresponding marker node and add it to a set - log.info("Found "+markerList.size()+ " markers in the marker file."); - for(int i = 1; i<markerList.size(); i++){ - - if(i%500 == 0){ - log.info("Collected "+i+" markers from the repository."); - } - - String markerSymbol = markerList.get(i).get(0); - - //skip all symbols with dot in them - if(markerSymbol.contains(".")){ - - MarkerLogEntity le = new MarkerLogEntity(this.getClass().getSimpleName(),"CRL", "-", "copy number alteration", "Not Specified", markerSymbol, "",""); - le.setMessage(markerSymbol +" is an unrecognised symbol"); - le.setType("ERROR"); - continue; - - } - - - //log.info("Looking up: "+markerSymbol); - NodeSuggestionDTO nsdto = dataImportService.getSuggestedMarker(this.getClass().getSimpleName(), "CRL", "-", markerSymbol, "copy number alteration", "Not Specified"); - - if(nsdto.getNode() == null){ - - //uh oh, we found an unrecognised marker symbol, abort, abort!!!! - reportManager.addMessage(nsdto.getLogEntity()); - - continue; - } - else{ - - Marker marker = (Marker) nsdto.getNode(); - markerSet.add(marker); - - } - - } - - - //STEP2: - - - UniversalLoader updog = new UniversalLoader(reportManager, utilityService, dataImportService); - updog.setFinderRootDir(finderRootDir); - - updog.initTemplates(templateFileStr); - - List<List<String>> datasetDerived = updog.getSamplePlatformDescriptionSheetData(); - int row = 6; - - for (List<String> derivedDatasetRow : datasetDerived) { - - String sampleId = derivedDatasetRow.get(0); - - String origin = derivedDatasetRow.get(1); - String passage = derivedDatasetRow.get(2); - String nomenclature = derivedDatasetRow.get(3); - String modelId = derivedDatasetRow.get(4); - String molCharType = derivedDatasetRow.get(5); - String platformName = derivedDatasetRow.get(6); - String platformTechnology = derivedDatasetRow.get(7); - String platformDescription = derivedDatasetRow.get(8); - String analysisProtocol = derivedDatasetRow.get(9); - - //SKIP everything that is not cna - if(!molCharType.toLowerCase().equals("copy number alteration")){ - - row++; - continue; - } - - platformName = platformName.replaceAll("[^A-Za-z0-9 _-]", ""); - - ModelCreation model; - Sample sample = null; - //patient sample - if (origin.toLowerCase().equals("patient")) { - - sample = dataImportService.findHumanSample(modelId, "CRL"); - - if (sample != null) { - - } - else { - - log.error("Unknown human sample with id: " + sampleId); - row++; - continue; - } - } - //xenograft sample - else if (origin.toLowerCase().equals("engrafted tumor") || origin.toLowerCase().equals("engrafted tumour") || origin.toLowerCase().equals("xenograft") ) { - - if (passage == null || passage.isEmpty() || passage.toLowerCase().equals("not specified")) { - - log.error("Missing essential value Xenograft Passage in row " + row); - row++; - continue; - } - - if (nomenclature == null || nomenclature.isEmpty()) { - - log.error("Missing essential value nomenclature in row " + row); - row++; - continue; - } - - //need this trick to get rid of 0.0 if there is any - //if(passage.equals("0.0")) passage = "0"; - int passageInt = (int) Float.parseFloat(passage); - passage = String.valueOf(passageInt); - - model = dataImportService.findModelByIdAndDataSourceWithSpecimensAndHostStrain(modelId, "CRL"); - - if(model == null){ - log.error("Model "+modelId + " not found, skipping"); - row++; - continue; - } - - //this specimen should have the appropriate hoststrain, too! - Specimen specimen = dataImportService.findSpecimenByModelAndPassageAndNomenclature(model, passage, nomenclature); - - if(specimen != null) { - - sample = specimen.getSample(); - - } - else{ - log.error("Specimen not found in row "+row); - row++; - continue; - } - - } - - //STEP3: find the proper molecular characterization node - MolecularCharacterization molChar = null; - - if(sample != null){ - - for(MolecularCharacterization mc : sample.getMolecularCharacterizations()){ - - if(mc.getType().equalsIgnoreCase(molCharType)){ - - if(mc.getPlatform() != null && mc.getPlatform().getName().equalsIgnoreCase(platformName)){ - - molChar = mc; - break; - } - } - - } - } - else{ - - log.error("Proper sample not found for data in row: "+row); - row++; - continue; - } - - - if(molChar != null){ - //STEP4: link molchar to the markers with a fake MA - int maCounter = 0; - MarkerAssociation ma = new MarkerAssociation(); - for(Marker m: markerSet){ - - - molChar.addMarkerAssociation(ma); - maCounter++; - if(maCounter !=0 && maCounter%500==0){ - dataImportService.saveMolecularCharacterization(molChar); - log.info("Saved "+maCounter+" associations for "+modelId); - } - - } - - //STEP5: save the modified molchar object - dataImportService.saveMolecularCharacterization(molChar); - log.info("Saved cna data for model: "+modelId); - - } - else{ - log.error("Proper MolChar object not found for data in row: "+row); - row++; - continue; - - } - - - - } - - - - } - - - } - - - - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - context = applicationContext; - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadHCI.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadHCI.java deleted file mode 100644 index e6bf7e9e62466966d6d699159a4e79f62952329b..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadHCI.java +++ /dev/null @@ -1,285 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.pdxfinder.services.dto.LoaderDTO; -import org.pdxfinder.services.dto.NodeSuggestionDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; - -import java.io.*; -import java.util.*; - - -@Service -@PropertySource("classpath:loader.properties") -@ConfigurationProperties(prefix = "hci") -public class LoadHCI extends LoaderBase { - - private final static Logger log = LoggerFactory.getLogger(LoadHCI.class); - - @Value("${data-dir}") - private String finderRootDir; - - public LoadHCI(UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - } - - public void run() throws Exception { - - initMethod(); - globalLoadingOrder(); - } - - - @Override - protected void initMethod() { - - log.info("Loading Huntsman PDX data. "); - - dto = new LoaderDTO(); - - jsonFile = finderRootDir + "/data/" + dataSourceAbbreviation + "/pdx/models.json"; - dataSource = dataSourceAbbreviation; - filesDirectory = ""; - } - - - - @Override - protected void step01GetMetaDataFolder() { } - - - - // HCI uses common implementation Steps step08GetMetaData,step09LoadPatientData default - - - @Override - protected void step10LoadExternalURLs() { - - loadExternalURLs(dataSourceContact,Standardizer.NOT_SPECIFIED); - } - - - @Override - protected void step11LoadBreastMarkers() { - - } - - // HCI uses common implementation Steps step12CreateModels default - - - @Override - protected void step13LoadSpecimens() { - - dto.getModelCreation().addRelatedSample(dto.getPatientSample()); - dto.getModelCreation().addGroup(providerDS); - - dataImportService.saveSample(dto.getPatientSample()); - dataImportService.savePatientSnapshot(dto.getPatientSnapshot()); - - EngraftmentSite engraftmentSite = dataImportService.getImplantationSite(dto.getImplantationSiteStr()); - EngraftmentType engraftmentType = dataImportService.getImplantationType(dto.getImplantationtypeStr()); - - // uggh parse strains - ArrayList<HostStrain> strainList= new ArrayList(); - String strains = dto.getStrain(); - if(strains.contains(" and ")){ - strainList.add(nsgBS); - strainList.add(nsBS); - }else if(strains.contains("gamma")){ - strainList.add(nsBS); - }else{ - strainList.add(nsBS); - } - - int count = 0; - for(HostStrain strain : strainList){ - count++; - Specimen specimen = new Specimen(); - specimen.setExternalId(dto.getModelID()+"-"+count); - specimen.setEngraftmentSite(engraftmentSite); - specimen.setEngraftmentType(engraftmentType); - specimen.setHostStrain(strain); - - Sample specSample = new Sample(); - specSample.setSourceSampleId(dto.getModelID()+"-"+count); - specimen.setSample(specSample); - - dto.getModelCreation().addSpecimen(specimen); - dto.getModelCreation().addRelatedSample(specSample); - dataImportService.saveSpecimen(specimen); - } - dataImportService.saveModelCreation(dto.getModelCreation()); - } - - - - - @Override - protected void step14LoadPatientTreatments() { - - - } - - - - - @Override - protected void step15LoadImmunoHistoChemistry() { - - String ihcFileStr = String.format("%s/data/%s/ihc/ihc.txt", finderRootDir, dataSourceAbbreviation); - - File file = new File(ihcFileStr); - - if (file.exists()) { - - Platform pl = dataImportService.getPlatform("immunohistochemistry","cytogenetics", providerDS); - - String currentLine = ""; - int currentLineCounter = 1; - String[] row; - - Map<String, MolecularCharacterization> molCharMap = new HashMap<>(); - - try { - BufferedReader buf = new BufferedReader(new FileReader(ihcFileStr)); - - while (true) { - currentLine = buf.readLine(); - if (currentLine == null) { - break; - //skip the first two rows - } else if (currentLineCounter < 3) { - currentLineCounter++; - continue; - - } else { - row = currentLine.split("\t"); - - if (row.length > 0) { - - String modelId = row[0]; - String sampleId = row[1]; - String markerSymbol = row[2]; - String result = row[3]; - //System.out.println(modelId); - - if (modelId.isEmpty() || sampleId.isEmpty() || markerSymbol.isEmpty() || result.isEmpty()) - continue; - - NodeSuggestionDTO nsdto = dataImportService.getSuggestedMarker(this.getClass().getSimpleName(), dataSource, modelId, markerSymbol, "cytogenetics","ImmunoHistoChemistry"); - Marker marker = null; - - - if(nsdto.getNode() == null){ - - //uh oh, we found an unrecognised marker symbol, abort, abort!!!! - reportManager.addMessage(nsdto.getLogEntity()); - continue; - } - else{ - - //we have a marker node, check message - - marker = (Marker)nsdto.getNode(); - - if(nsdto.getLogEntity() != null){ - reportManager.addMessage(nsdto.getLogEntity()); - } - - MolecularCharacterization mc; - - if (molCharMap.containsKey(modelId + "---" + sampleId)) { - - mc = molCharMap.get(modelId + "---" + sampleId); - } - else { - - mc = new MolecularCharacterization(); - mc.setType("cytogenetics"); - mc.setPlatform(pl); - MarkerAssociation ma = new MarkerAssociation(); - mc.addMarkerAssociation(ma); - - - molCharMap.put(modelId + "---" + sampleId, mc); - } - - MolecularData molecularData = new MolecularData(); - molecularData.setMarker(marker.getHgncSymbol()); - molecularData.setCytogeneticsResult(result); - mc.getFirstMarkerAssociation().addMolecularData(molecularData); - mc.addMarker(molecularData.getMarker()); - } - - - - } - - - } - } - } catch (Exception e) { - e.printStackTrace(); - System.out.println(currentLineCounter + " " + currentLine.toString()); - } - - //System.out.println(molCharMap.toString()); - - for (Map.Entry<String, MolecularCharacterization> entry : molCharMap.entrySet()) { - String key = entry.getKey(); - MolecularCharacterization mc = entry.getValue(); - - String[] modAndSamp = key.split("---"); - String modelId = modAndSamp[0]; - String sampleId = modAndSamp[1]; - - //Sample sample = dataImportService.findMouseSampleWithMolcharByModelIdAndDataSourceAndSampleId(modelId, hciDS.getAbbreviation(), sampleId); - Sample sample = dataImportService.findHumanSampleWithMolcharByModelIdAndDataSource(modelId, providerDS.getAbbreviation()); - - if (sample == null) { - log.warn("Missing model or sample: " + modelId + " " + sampleId); - continue; - } - - sample.addMolecularCharacterization(mc); - mc.getFirstMarkerAssociation().encodeMolecularData(); - dataImportService.saveSample(sample); - - } - - } else { - - log.warn("Skipping loading IHC for HCI"); - } - - } - - - - @Override - protected void step16LoadVariationData() { } - - - @Override - void step17LoadModelDosingStudies() throws Exception { - - loadModelDosingStudies(); - } - - @Override - void step18SetAdditionalGroups() { - throw new UnsupportedOperationException(); - } - - - - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadIRCC.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadIRCC.java deleted file mode 100644 index cd0d67ab55b2f3cab897c7eb4accbeb64b840572..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadIRCC.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.pdxfinder.dataloaders; - -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONException; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.*; - -@Service -@PropertySource("classpath:loader.properties") -@ConfigurationProperties(prefix = "ircc") -public class LoadIRCC extends LoaderBase { - private static final Logger log = LoggerFactory.getLogger(LoadIRCC.class); - - // samples -> markerAsssociations - private HashMap<String, HashSet<MarkerAssociation>> markerAssociations = new HashMap(); - private HashMap<String, HashMap<String, String>> specimenSamples = new HashMap(); - private HashSet<Integer> loadedModelHashes = new HashSet<>(); - - @Value("${data-dir}") - private String finderRootDir; - - @Value("${irccpdx.variation.max}") - private int variationMax; - - public LoadIRCC(UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - } - - public void run() throws Exception { - - initMethod(); - irccAlgorithm(); - } - - - public void irccAlgorithm() throws Exception { - - step00StartReportManager(); - step02GetMetaDataJSON(); - if (skipThis) return; - step03CreateProviderGroup(); - step04CreateNSGammaHostStrain(); - step06SetProjectGroup(); - step07GetPDXModels(); - - for (int i = 0; i < jsonArray.length(); i++) { - this.jsonData = jsonArray.getJSONObject(i); - - if (loadedModelHashes.contains(jsonData.toString().hashCode())) continue; - loadedModelHashes.add(jsonData.toString().hashCode()); - - step08GetMetaData(); - step09LoadPatientData(); - step10LoadExternalURLs(); - step12CreateModels(); - step13LoadSpecimens(); - step17LoadModelDosingStudies(); - step16LoadVariationData(); - step18SetAdditionalGroups(); - } - } - - @Override - protected void initMethod() { - log.info("Loading IRCC PDX data."); - finderRootDir = UniversalLoader.stripTrailingSlash(finderRootDir); - jsonFile = finderRootDir + "/data/" + dataSourceAbbreviation+"/pdx/models.json"; - - dataSource = dataSourceAbbreviation; - filesDirectory = ""; - - platformURL = new HashMap<>(); - platformURL.put("whole exome sequencing_mutation","/platform/whole-exome-sequencing/"); - platformURL.put("TargetedNGS_MUT_mutation","/platform/ircc-gene-panel/"); - platformURL.put("Targeted Next Generation Sequencing_copy number alteration","/platform/ircc-gene-panel/"); - - } - - @Override - protected void step01GetMetaDataFolder() { - throw new UnsupportedOperationException(); - } - - @Override - protected void step05CreateNSHostStrain() { - throw new UnsupportedOperationException(); - } - - @Override - protected void step10LoadExternalURLs() { - loadExternalURLs(dataSourceContact,Standardizer.NOT_SPECIFIED); - dataImportService.saveSample(dto.getPatientSample()); - dataImportService.savePatientSnapshot(dto.getPatientSnapshot()); - } - - @Override - protected void step11LoadBreastMarkers() { - throw new UnsupportedOperationException(); - } - - @Override - protected void step13LoadSpecimens()throws Exception { - - dto.getModelCreation().addGroup(providerDS); - - JSONArray specimens = dto.getSpecimens(); - - for (int i = 0; i < specimens.length(); i++) { - JSONObject specimenJSON = specimens.getJSONObject(i); - - String specimenId = specimenJSON.getString("Specimen ID"); - Specimen specimen = dataImportService.getSpecimen( - dto.getModelCreation(), - specimenId, - providerDS.getAbbreviation(), - specimenJSON.getString("Passage")); - specimen.setHostStrain(nsgBS); - - EngraftmentSite is = dataImportService.getImplantationSite(specimenJSON.getString("Engraftment Site")); - specimen.setEngraftmentSite(is); - EngraftmentType it = dataImportService.getImplantationType("Heterotopic"); - specimen.setEngraftmentType(it); - - EngraftmentMaterial em = dataImportService.getEngraftmentMaterial(specimenJSON.getString("Engraftment Type")); - specimen.setEngraftmentMaterial(em); - - Sample specSample = new Sample(); - specSample.setSourceSampleId(specimenId); - specSample.setDataSource(providerDS.getAbbreviation()); - - specimen.setSample(specSample); - - dto.getModelCreation().addSpecimen(specimen); - dto.getModelCreation().addRelatedSample(specSample); - - } - } - - @Override - protected void step14LoadPatientTreatments() { - throw new UnsupportedOperationException(); - } - - @Override - protected void step15LoadImmunoHistoChemistry() { - throw new UnsupportedOperationException(); - } - - @Override - protected void step16LoadVariationData() { - log.info(String.format("Loading WGS for model %s", dto.getModelCreation().getSourcePdxId())); - loadOmicData(dto.getModelCreation(), providerDS,"mutation", finderRootDir+"/data/"+dataSource); - loadOmicData(dto.getModelCreation(), providerDS,"copy number alteration", finderRootDir+"/data/"+dataSource); - } - - @Override - void step17LoadModelDosingStudies() { - TreatmentSummary ts; - if (dto.getModelDosingStudies().length() > 0) { - ts = new TreatmentSummary(); - ts.setUrl(dosingStudyURL); - - for (int t = 0; t < dto.getModelDosingStudies().length(); t++) { - try { - JSONObject treatmentObject = dto.getModelDosingStudies().getJSONObject(t); - TreatmentProtocol treatmentProtocol = dataImportService.getTreatmentProtocol(treatmentObject.getString("Drug"), - treatmentObject.getString("Dose"), - treatmentObject.getString("Response Class"), ""); - - if (treatmentProtocol != null) { - ts.addTreatmentProtocol(treatmentProtocol); - } - } catch (JSONException e) { - log.error(e.toString()); - } - ts.setModelCreation(dto.getModelCreation()); - dto.getModelCreation().setTreatmentSummary(ts); - } - } - - dataImportService.saveModelCreation(dto.getModelCreation()); - - dataImportService.savePatient(dto.getPatient()); - dataImportService.savePatientSnapshot(dto.getPatientSnapshot()); - dataImportService.saveModelCreation(dto.getModelCreation()); - - } - - @Override - protected void step18SetAdditionalGroups() { - Group access = dataImportService.getAccessibilityGroup( - validateAccessibility(""), - validateModality("transnational access") - ); - - Group project = dataImportService.getProjectGroup("EurOPDX"); - - dto.getModelCreation().addGroup(access); - dto.getModelCreation().addGroup(project); - dataImportService.saveModelCreation(dto.getModelCreation()); - } - - - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadJAXData.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadJAXData.java index 75db36b3536af63edb7b610b8640ddf170ff0be1..cd1ac8daeaac4cd82f335e2d5333998b8f18b178 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadJAXData.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadJAXData.java @@ -1,8 +1,7 @@ package org.pdxfinder.dataloaders; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.graph.dao.*; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.UtilityService; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadMDAnderson.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadMDAnderson.java deleted file mode 100644 index 520ba7f1a4816d29bc4864801c18ceee035097a1..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadMDAnderson.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.pdxfinder.dataloaders; - -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Options; -import org.neo4j.ogm.session.Session; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.pdxfinder.services.dto.LoaderDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; - -@Service -@PropertySource("classpath:loader.properties") -@ConfigurationProperties(prefix = "mda") -public class LoadMDAnderson extends LoaderBase { - - private final static Logger log = LoggerFactory.getLogger(LoadMDAnderson.class); - - // private HostStrain nsgBS; - private Group mdaDS; - private Group projectGroup; - - private Session session; - - @Value("${data-dir}") - private String finderRootDir; - - public LoadMDAnderson(UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - } - - public void run() throws Exception { - - initMethod(); - mdAndersonAlgorithm(); - } - - - - public void mdAndersonAlgorithm() throws Exception { - - step00StartReportManager(); - - step01GetMetaDataFolder(); - - if (skipThis) return; - - for (int i = 0; i < listOfFiles.length; i++) { - - if (listOfFiles[i].isFile()) { - - this.jsonFile = rootDataDirectory +"/" + dataSourceAbbreviation + "/pdx/" + listOfFiles[i].getName(); - globalLoadingOrder(); - } - } - - log.info("Finished loading " + dataSourceAbbreviation + " PDX data."); - } - - - - @Override - protected void initMethod() { - - log.info("Loading MDAnderson PDX data."); - - dto = new LoaderDTO(); - rootDataDirectory = finderRootDir + "/data"; - dataSource = dataSourceAbbreviation; - filesDirectory = finderRootDir + "/data/" + dataSourceAbbreviation + "/pdx/"; - } - - // MD ANDERSON uses default implementation Steps step01GetMetaDataFolder, step02GetMetaDataJSON - - @Override - protected void step04CreateNSGammaHostStrain() { - - } - - @Override - protected void step05CreateNSHostStrain() { - - } - - - // MD ANDERSON uses default implementation Steps step08GetMetaData, step09LoadPatientData - - - @Override - protected void step10LoadExternalURLs() { - - loadExternalURLs(dataSourceContact,Standardizer.NOT_SPECIFIED); - - } - - - @Override - protected void step11LoadBreastMarkers() { - - } - - - // IRCC uses default implementation Steps Step11CreateModels default - - - @Override - protected void step13LoadSpecimens()throws Exception { - - loadSpecimens("mdAnderson"); - - } - - - @Override - protected void step14LoadPatientTreatments() { - - } - - - @Override - protected void step15LoadImmunoHistoChemistry() { - - } - - - @Override - protected void step16LoadVariationData() { - - } - - @Override - void step17LoadModelDosingStudies() throws Exception { - - } - - @Override - void step18SetAdditionalGroups() { - throw new UnsupportedOperationException(); - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadPDMRData.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadPDMRData.java deleted file mode 100644 index 96d96e81af97cec4db77218508f951bc0b177ffd..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadPDMRData.java +++ /dev/null @@ -1,261 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.dto.LoaderDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; - -import java.util.*; - -@Service -@PropertySource("classpath:loader.properties") -@ConfigurationProperties(prefix = "pdmr") -public class LoadPDMRData extends LoaderBase { - - private final static Logger log = LoggerFactory.getLogger(LoadPDMRData.class); - - @Value("${data-dir}") - private String finderRootDir; - - - public LoadPDMRData(UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - } - - - - public void run() throws Exception{ - - initMethod(); - globalLoadingOrder(); - - } - - - @Override - protected void initMethod() { - - log.info("Loading PDMR PDX data."); - - dto = new LoaderDTO(); - - jsonFile = finderRootDir +"/data/"+dataSourceAbbreviation+"/pdx/models.json"; - dataSource = dataSourceAbbreviation; - - platformURL = new HashMap<>(); - platformURL.put("NCI cancer gene panel_mutation","/platform/pdmr-mut-ts"); - } - - - @Override - protected void step01GetMetaDataFolder() { - - } - - // PDMR uses default implementation Steps step02GetMetaDataJSON - - @Override - protected void step05CreateNSHostStrain() { - - } - - - @Override - protected void step06SetProjectGroup() { - - } - - // PDMR uses default implementation Steps step08GetMetaData - - @Override - protected void step09LoadPatientData() { - - if (dataImportService.isExistingModel(providerDS.getAbbreviation(), dto.getModelID())) return; - super.step09LoadPatientData(); - } - - - @Override - protected void step10LoadExternalURLs() { - - dataImportService.savePatientSnapshot(dto.getPatientSnapshot()); - loadExternalURLs(dataSourceContact, dto.getSourceURL()); - } - - - @Override - protected void step11LoadBreastMarkers() { - - } - - - - @Override - protected void step12CreateModels() throws Exception { - - List<QualityAssurance> validationList = new ArrayList<>(); - if(dto.getValidationsArr().length() > 0){ - - for(int k=0; k<dto.getValidationsArr().length(); k++){ - - JSONObject validationObj = dto.getValidationsArr().getJSONObject(k); - QualityAssurance qa = new QualityAssurance(validationObj.getString("Technique"), validationObj.getString("Description"), validationObj.getString("Passage")); - validationList.add(qa); - } - } - - ModelCreation modelCreation = dataImportService.createModelCreation(dto.getModelID(), providerDS.getAbbreviation(), dto.getPatientSample(), validationList, dto.getExternalUrls()); - modelCreation.addRelatedSample(dto.getPatientSample()); - dto.setModelCreation(modelCreation); - } - - - - @Override - protected void step13LoadSpecimens()throws Exception { - - //load specimens - if(dto.getSamplesArr().length() > 0){ - for(int i=0; i<dto.getSamplesArr().length();i++){ - - JSONObject sampleObj = dto.getSamplesArr().getJSONObject(i); - String sampleType = sampleObj.getString("Tumor Type"); - - if(sampleType.equals("engrafted Tumor")){ - - String specimenId = sampleObj.getString("Sample ID"); - String passage = sampleObj.getString("Passage"); - - Specimen specimen = dataImportService.getSpecimen(dto.getModelCreation(), - specimenId, providerDS.getAbbreviation(), passage); - - specimen.setHostStrain(nsgBS); - - EngraftmentSite es = dataImportService.getImplantationSite(dto.getImplantationSiteStr()); - specimen.setEngraftmentSite(es); - - EngraftmentType et = dataImportService.getImplantationType(dto.getImplantationtypeStr()); - specimen.setEngraftmentType(et); - - Sample specSample = new Sample(); - - specSample.setSourceSampleId(specimenId); - specSample.setDataSource(providerDS.getAbbreviation()); - - specimen.setSample(specSample); - - dto.getModelCreation().addSpecimen(specimen); - dto.getModelCreation().addRelatedSample(specSample); - - } - - } - } - } - - - - - @Override - protected void step14LoadPatientTreatments() throws Exception { - - TreatmentSummary ts; - - //Disable loading treatment temporarily, drug names are not harmonized! - Boolean loadTreatment = true; - //don't create two treatmentsummaries for the same snapshot - if(loadTreatment && dataImportService.findTreatmentSummaryByPatientSnapshot(dto.getPatientSnapshot()) == null){ - ts = new TreatmentSummary(); - - JSONArray treatmentArr = dto.getPatientTreatments(); - - for(int k=0; k<treatmentArr.length();k++){ - - JSONObject treatmentObj = treatmentArr.getJSONObject(k); - TreatmentProtocol tp = null; - - String drugString = ""; - String date = ""; - String duration = treatmentObj.getString("Duration"); - String response = treatmentObj.getString("Response"); - Boolean currentTreatment = false; - - try { - //this is the current treatment - if (treatmentObj.has("Current Drug")) { - - drugString = treatmentObj.getString("Current Drug"); - date = treatmentObj.getString("Starting Date"); - currentTreatment = true; - - } - //not current treatment, create default TreatmentProtocol object - else { - - drugString = treatmentObj.getString("Prior Drug"); - date = treatmentObj.getString("Prior Date"); - currentTreatment = false; - - } - - if (drugString.equals("Released at Trial Closure") || drugString.equals("No Current Therapy") || drugString.toLowerCase().equals("treatment naive")) continue; - tp = dataImportService.getTreatmentProtocol(drugString, "", response, currentTreatment); - - } - catch(Exception e){ - e.printStackTrace(); - log.error("Error loading treatment. Model: "+dto.getModelID() +" Drugstring: "+drugString); - } - if(tp != null) { - tp.setTreatmentDate(date); - tp.addDurationForAllComponents(duration); - ts.addTreatmentProtocol(tp); - } - } - - //save summary on snapshot - if(ts.getTreatmentProtocols() != null && ts.getTreatmentProtocols().size() > 0){ - dto.getPatientSnapshot().setTreatmentSummary(ts); - dataImportService.savePatientSnapshot(dto.getPatientSnapshot()); - } - - } - dataImportService.saveModelCreation(dto.getModelCreation()); - - } - - - @Override - protected void step15LoadImmunoHistoChemistry() { - - } - - - @Override - protected void step16LoadVariationData() { - - log.info("Loading NGS for model " + dto.getModelCreation().getSourcePdxId()); - - loadOmicData(dto.getModelCreation(), providerDS, "mutation",finderRootDir+"/data/"+dataSourceAbbreviation); - } - - - @Override - void step17LoadModelDosingStudies() throws Exception { - - } - - @Override - void step18SetAdditionalGroups() { - throw new UnsupportedOperationException(); - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadUniversal.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadUniversal.java deleted file mode 100644 index 24e4c1c88e5536e36f1260111b38b0bcefc39fbc..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadUniversal.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContextAware; -import org.pdxfinder.reportmanager.ReportManager; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Service; -import java.io.File; -import java.nio.file.Paths; - - -@Service -public class LoadUniversal implements ApplicationContextAware { - - @Value("${data-dir}") - private String finderRootDir; - - private Logger log = LoggerFactory.getLogger(LoadUniversal.class); - - private static ApplicationContext context; - - private ReportManager reportManager; - - @Autowired - private DataImportService dataImportService; - - @Autowired - private UtilityService utilityService; - - - public void run(String dataProvider) throws Exception { - - finderRootDir = UniversalLoader.stripTrailingSlash(finderRootDir); - - String updogDir = String.format("%s/data/UPDOG", finderRootDir); - - String providerDir = String.format("%s/%s", updogDir, dataProvider.replace("_","-")); - - reportManager = (ReportManager) context.getBean("ReportManager"); - - File folder = new File(updogDir); - - if (folder.exists()) { - - File dataDir = Paths.get(providerDir).toFile(); - - if (dataDir.isDirectory()) { - - log.info("******************************************************"); - log.info("* Starting universal loader for {} *", dataProvider); - log.info("******************************************************"); - log.info("Loading data from {} ", providerDir); - UniversalLoader updog = new UniversalLoader(reportManager, utilityService, dataImportService); - updog.setFinderRootDir(finderRootDir); - updog.initTemplates(providerDir); - updog.loadTemplateData(); - - log.info("******************************************************"); - log.info("* Finished running universal loader for {} *", dataProvider); - log.info("******************************************************"); - - } - - } - //NO UNIVERSAL TEMPLATES, SKIP - else { - - log.warn("No UPDOG directory found. Who let the dog out?"); - } - - } - - - public LoadUniversal(DataImportService dataImportService) { - this.dataImportService = dataImportService; - } - - public LoadUniversal() { - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.context = applicationContext; - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWISTAR.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWISTAR.java deleted file mode 100644 index e3111e60f0f83551f0a99dd9c58575768bb2368b..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWISTAR.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -@Service -public class LoadWISTAR { - - private final static Logger log = LoggerFactory.getLogger(LoadWISTAR.class); - - private final static String DATASOURCE_ABBREVIATION = "PDXNet-Wistar-MDAnderson-Penn"; - private final static String DATASOURCE_NAME = "Wistar/MD Anderson/Penn"; - private final static String DATASOURCE_DESCRIPTION = "Wistar-MDAnderson-Penn PDX mouse models for PDXNet."; - private final static String DATASOURCE_CONTACT = "herlynm@Wistar.org,MDavies@mdanderson.org"; - private final static String SOURCE_URL = null; - - private final static String PROVIDER_TYPE = ""; - private final static String ACCESSIBILITY = ""; - - // for now all samples are of tumor tissue - private final static Boolean NORMAL_TISSUE_FALSE = false; - - private final static String NOT_SPECIFIED = Standardizer.NOT_SPECIFIED; - - // private HostStrain nsgBS; - private Group wistarDS; - private Group projectGroup; - - private DataImportService dataImportService; - private UtilityService utilityService; - - @Value("${data-dir}") - private String finderRootDir; - - public LoadWISTAR(DataImportService dataImportService, - UtilityService utilityService) { - this.dataImportService = dataImportService; - this.utilityService = utilityService; - } - - public void run() throws Exception { - - String urlStr = finderRootDir+ "/data/" +DATASOURCE_ABBREVIATION+"/pdx/models.json"; - File file = new File(urlStr); - if(file.exists()){ - - log.info("Loading WISTAR PDX data from URL " + urlStr); - parseJSON(utilityService.parseFile(urlStr)); - } - else{ - - log.info("No file found for "+DATASOURCE_ABBREVIATION+", skipping"); - } - - } - - private void parseJSON(String json) { - - wistarDS = dataImportService.getProviderGroup(DATASOURCE_NAME, DATASOURCE_ABBREVIATION, - DATASOURCE_DESCRIPTION, PROVIDER_TYPE, DATASOURCE_CONTACT, SOURCE_URL); - - // nsgBS = loaderUtils.getHostStrain(NSG_BS_SYMBOL, NSG_BS_NAME, NSG_BS_NAME, NSG_BS_URL); - - projectGroup = dataImportService.getProjectGroup("PDXNet"); - - try { - JSONObject job = new JSONObject(json); - JSONArray jarray = job.getJSONArray("WISTAR"); - - for (int i = 0; i < jarray.length(); i++) { - - JSONObject j = jarray.getJSONObject(i); - - createGraphObjects(j); - } - - } catch (Exception e) { - log.error("Error getting WISTAR PDX models", e); - - } - } - - @Transactional - void createGraphObjects(JSONObject j) throws Exception { - String id = j.getString("Model ID").trim(); - - // the preference is for histology - String diagnosis = j.getString("Clinical Diagnosis"); - String histology = j.getString("Histology"); - - if (histology.trim().length() > 0) { - diagnosis = histology; - } - - if (diagnosis.trim().length() == 0) { - // no histology no diagnosis -> no model - return; - } - - String classification = j.getString("Stage") + "/" + j.getString("Grades"); - String stage = j.getString("Stage"); - String grade = j.getString("Grades"); - - String ethnicity = NOT_SPECIFIED; - try { - if (j.getString("Race").trim().length() > 0) { - ethnicity = j.getString("Race"); - } - } catch (Exception e) { - } - - try { - if (j.getString("Ethnicity").trim().length() > 0) { - ethnicity = j.getString("Ethnicity"); - } - } catch (Exception e) { - } - - String age = Standardizer.getAge(j.getString("Age")); - - String gender = Standardizer.getGender(j.getString("Gender")); - String patientId = j.getString("Patient ID"); - - String tumorType = Standardizer.getTumorType(j.getString("Tumor Type")); - String extractionMethod = j.getString("Sample Type"); - - Patient patient = dataImportService.getPatientWithSnapshots(patientId, wistarDS); - - if(patient == null){ - - patient = dataImportService.createPatient(patientId, wistarDS, gender, "", Standardizer.getEthnicity(ethnicity)); - } - - PatientSnapshot pSnap = dataImportService.getPatientSnapshot(patient, age, "", "", ""); - - - //String sourceSampleId, String dataSource, String typeStr, String diagnosis, String originStr, - //String sampleSiteStr, String extractionMethod, Boolean normalTissue, String stage, String stageClassification, - // String grade, String gradeClassification - Sample sample = dataImportService.getSample(id, wistarDS.getAbbreviation(), tumorType, diagnosis, NOT_SPECIFIED, - NOT_SPECIFIED, extractionMethod, false, stage, "", grade, ""); - - - - - pSnap.addSample(sample); - - dataImportService.saveSample(sample); - dataImportService.savePatientSnapshot(pSnap); - - List<ExternalUrl> externalUrls = new ArrayList<>(); - externalUrls.add(dataImportService.getExternalUrl(ExternalUrl.Type.CONTACT, DATASOURCE_CONTACT)); - - String qaType = NOT_SPECIFIED; - try { - qaType = j.getString("QA") + "on passage " + j.getString("QA Passage"); - } catch (Exception e) { - // not all groups supplied QA - } - String qaPassage = j.has("QA Passage") ? j.getString("QA Passage") : null; - - QualityAssurance qa = new QualityAssurance(qaType, - NOT_SPECIFIED, qaPassage); - dataImportService.saveQualityAssurance(qa); - - String strain = j.getString("Strain"); - HostStrain bs = dataImportService.getHostStrain("", strain, "", ""); - - String engraftmentSite = Standardizer.getValue("Engraftment Site", j); - - String tumorPrep = Standardizer.getValue("Tumor Prep", j); - - ModelCreation modelCreation = dataImportService.createModelCreation(id, wistarDS.getAbbreviation(), sample, qa, externalUrls); - modelCreation.addRelatedSample(sample); - modelCreation.addGroup(projectGroup); - - Specimen specimen = dataImportService.getSpecimen(modelCreation, - modelCreation.getSourcePdxId(), wistarDS.getAbbreviation(), NOT_SPECIFIED); - - specimen.setHostStrain(bs); - - EngraftmentSite is = dataImportService.getImplantationSite(engraftmentSite); - specimen.setEngraftmentSite(is); - - EngraftmentType it = dataImportService.getImplantationType(tumorPrep); - specimen.setEngraftmentType(it); - - Sample xenoSample = new Sample(); - xenoSample.setSourceSampleId(modelCreation.getSourcePdxId()); - specimen.setSample(xenoSample); - modelCreation.addRelatedSample(xenoSample); - modelCreation.addSpecimen(specimen); - dataImportService.saveSpecimen(specimen); - - dataImportService.saveModelCreation(modelCreation); - - } - - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWUSTL.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWUSTL.java deleted file mode 100644 index 65af4e2f65a474e86b32697dddee6add4344c127..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoadWUSTL.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.pdxfinder.services.dto.LoaderDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.PropertySource; -import org.springframework.stereotype.Service; - -@Service -@PropertySource("classpath:loader.properties") -@ConfigurationProperties(prefix = "wustl") -public class LoadWUSTL extends LoaderBase { - - private final static Logger log = LoggerFactory.getLogger(LoadWUSTL.class); - - private Group DS; - private Group projectGroup; - - @Value("${data-dir}") - private String finderRootDir; - - public LoadWUSTL(UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - } - - public void run() throws Exception { - initMethod(); - wustlAlgorithm(); - - } - - public void wustlAlgorithm() throws Exception { - - step00StartReportManager(); - - step01GetMetaDataFolder(); - - if (skipThis) return; - - for (int i = 0; i < listOfFiles.length; i++) { - - if (listOfFiles[i].isFile()) { - - this.jsonFile = rootDataDirectory + "/data/" + dataSourceAbbreviation + "/pdx/" + listOfFiles[i].getName(); - globalLoadingOrder(); - } - } - log.info("Finished loading " + dataSourceAbbreviation + " PDX data."); - } - - - @Override - protected void initMethod() { - - log.info("Loading WUSTL PDX data."); - - dto = new LoaderDTO(); - rootDataDirectory = finderRootDir; - dataSource = dataSourceAbbreviation; - filesDirectory = finderRootDir +"/data/" + dataSourceAbbreviation + "/pdx/"; - } - - // WUSTL uses default implementation Steps step01GetMetaDataFolder, step02GetMetaDataJSON - - @Override - protected void step04CreateNSGammaHostStrain() { - - } - - @Override - protected void step05CreateNSHostStrain() { - - } - - // WUSTL uses default implementation Steps step08GetMetaData, step09LoadPatientData - - @Override - protected void step10LoadExternalURLs() { - - loadExternalURLs(dataSourceContact,Standardizer.NOT_SPECIFIED); - - } - - @Override - protected void step11LoadBreastMarkers() { - - } - - // WUSTL uses default implementation Steps step12CreateModels default - - @Override - protected void step13LoadSpecimens()throws Exception { - - loadSpecimens("wustl"); - } - - - @Override - protected void step14LoadPatientTreatments() { - - } - - - @Override - protected void step15LoadImmunoHistoChemistry() { - - } - - - @Override - protected void step16LoadVariationData() { - - } - - @Override - void step17LoadModelDosingStudies() throws Exception { - - } - - @Override - void step18SetAdditionalGroups() { - throw new UnsupportedOperationException(); - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/LoaderBase.java b/indexer/src/main/java/org/pdxfinder/dataloaders/LoaderBase.java index 01b88dd8ef0d4555acffece2b2dd6388d583e93d..06ddccca7a38dd7ce9f9e2d0b650b06cfaf67ca3 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/LoaderBase.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/LoaderBase.java @@ -1,7 +1,7 @@ package org.pdxfinder.dataloaders; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.JSONArray; +import com.github.openjson.JSONObject; import org.pdxfinder.graph.dao.*; import org.pdxfinder.reportmanager.ReportManager; import org.pdxfinder.services.DataImportService; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/UniversalLoader.java b/indexer/src/main/java/org/pdxfinder/dataloaders/UniversalLoader.java deleted file mode 100644 index 98515024da5d27b8c05a3137725d1dae390540ac..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/UniversalLoader.java +++ /dev/null @@ -1,1499 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.reportmanager.ReportManager; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.pdxfinder.services.ds.Standardizer; -import org.pdxfinder.services.dto.NodeSuggestionDTO; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Component; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.*; - -/** - * Univeral Loader, aka UPDOG: Universal PdxData tO Graph - * - * "What's UPDOG?" - * "Nothing much, what's up with you?" - * Comments may contain egregious dog puns. - */ -@Component -public class UniversalLoader extends UniversalLoaderOmic { - - private final static Logger log = LoggerFactory.getLogger(UniversalLoader.class); - static ApplicationContext context; - ReportManager reportManager; - - private String finderRootDir; - private String dataRootDirectory; - - private List<List<String>> patientSheetData; - private List<List<String>> patientTumorSheetData; - private List<List<String>> patientTreatmentSheetData; - private List<List<String>> pdxModelSheetData; - private List<List<String>> pdxModelValidationSheetData; - private List<List<String>> samplePlatformDescriptionSheetData; - private List<List<String>> sharingAndContactSheetData; - private List<List<String>> cytogeneticsSheetData; - private List<List<String>> loaderRelatedDataSheetData; - private List<List<String>> drugDosingSheetData; - - private Group ds; - private Boolean stopLoading; - private Set<String> modelIDs; - - public UniversalLoader(ReportManager reportManager, UtilityService utilityService, DataImportService dataImportService) { - super(utilityService, dataImportService); - this.reportManager = reportManager; - } - - - public void initTemplates(String updogCurrDir) { - - log.info("******************************************************"); - log.info("* Initializing Sheet data *"); - log.info("******************************************************"); - - ds = null; - stopLoading = false; - - patientSheetData = new ArrayList<>(); - patientTumorSheetData = new ArrayList<>(); - pdxModelSheetData = new ArrayList<>(); - pdxModelValidationSheetData = new ArrayList<>(); - sharingAndContactSheetData = new ArrayList<>(); - loaderRelatedDataSheetData = new ArrayList<>(); - Optional<Workbook> metadata = getWorkbook(updogCurrDir, "metadata.xlsx"); - if (metadata.isPresent()) { - initializeSheetData(metadata.get().getSheetAt(1), patientSheetData); - initializeSheetData(metadata.get().getSheetAt(2), patientTumorSheetData); - initializeSheetData(metadata.get().getSheetAt(3), pdxModelSheetData); - initializeSheetData(metadata.get().getSheetAt(4), pdxModelValidationSheetData); - initializeSheetData(metadata.get().getSheetAt(5), sharingAndContactSheetData); - initializeSheetData(metadata.get().getSheetAt(6), loaderRelatedDataSheetData); - } - - samplePlatformDescriptionSheetData = new ArrayList<>(); - Optional<Workbook> samplePlatformDescription = getWorkbook(updogCurrDir, "sampleplatform.xlsx"); - if (samplePlatformDescription.isPresent()) { - initializeSheetData(samplePlatformDescription.get().getSheetAt(0), samplePlatformDescriptionSheetData); - } - - cytogeneticsSheetData = new ArrayList<>(); - Optional<Workbook> cytogenetics = getWorkbook(updogCurrDir, "cyto/cytogenetics.xlsx"); - if (cytogenetics.isPresent()) { - initializeSheetData(cytogenetics.get().getSheetAt(0), cytogeneticsSheetData); - } - - patientTreatmentSheetData = new ArrayList<>(); - Optional<Workbook> patientTreatment = getWorkbook(updogCurrDir, "treatment/patienttreatment.xlsx"); - if (patientTreatment.isPresent()) { - initializeSheetData(patientTreatment.get().getSheetAt(0), patientTreatmentSheetData); - } - - drugDosingSheetData = new ArrayList<>(); - Optional<Workbook> drugDosing = getWorkbook(updogCurrDir, "treatment/drugdosing.xlsx"); - if (drugDosing.isPresent()) { - initializeSheetData(drugDosing.get().getSheetAt(0), drugDosingSheetData); - } - } - - - public void loadTemplateData() { - - //:: DON'T CHANGE THE ORDER OF THESE METHODS UNLESS YOU WANT TO RISK THE UNIVERSE TO COLLAPSE! - createDataSourceGroup(); - createPatients(); - createPatientTumors(); - createPdxModelDetails(); - createPdxModelValidations(); - createSharingAndContacts(); - createDerivedPatientModelDataset(); - createPatientTreatments(); - createOmicData(); - createCytogeneticsData(); - - } - - public Optional<Workbook> getWorkbook(String updogCurrDir, String templatePath) { - templatePath = String.join("/", updogCurrDir, templatePath); - File file = new File(templatePath); - log.debug("Loading template {}", templatePath); - if (!file.exists()) return Optional.empty(); - - try (FileInputStream fileInputStream = new FileInputStream(file)) { - XSSFWorkbook workbook = new XSSFWorkbook(fileInputStream); - return Optional.of(workbook); - - } catch (IOException e) { - log.error("There was a problem accessing the file: {}", file, e); - } - return Optional.empty(); - } - - /** - * Loads the data from a spreadsheet tab into a placeholder - * - * @param sheet - * @param sheetData - */ - private void initializeSheetData(Sheet sheet, List<List<String>> sheetData) { - - Iterator<Row> iterator = sheet.iterator(); - int rowCounter = 0; - while (iterator.hasNext()) { - - Row currentRow = iterator.next(); - rowCounter++; - - if (rowCounter < 6) continue; - - Iterator<Cell> cellIterator = currentRow.iterator(); - List dataRow = new ArrayList(); - boolean isFirstColumn = true; - while (cellIterator.hasNext()) { - - Cell currentCell = cellIterator.next(); - //skip the first column - if (isFirstColumn) { - isFirstColumn = false; - continue; - } - - //getCellTypeEnum shown as deprecated for version 3.15 - //getCellTypeEnum will be renamed to getCellType starting from version 4.0 - - String value = null; - switch (currentCell.getCellType()) { - case Cell.CELL_TYPE_STRING: - value = currentCell.getStringCellValue(); - break; - case Cell.CELL_TYPE_BOOLEAN: - value = String.valueOf(currentCell.getBooleanCellValue()); - break; - case Cell.CELL_TYPE_NUMERIC: - value = String.valueOf(currentCell.getNumericCellValue()); - break; - } - - dataRow.add(value); - } - //check if there is some data in the row and they are not all nulls - if (dataRow.size() > 0 && !isRowOfNulls(dataRow)) { - - sheetData.add(dataRow); - - - } - - } - } - - - /** - * Creates the provider group in the database - */ - private void createDataSourceGroup() { - - - log.info("******************************************************"); - log.info("* Creating DataSource *"); - log.info("******************************************************"); - - - if (loaderRelatedDataSheetData.size() != 1) { - stopLoading = true; - - log.error("Zero or multiple provider definitions! Loading process is terminated."); - return; - } - - String providerName = loaderRelatedDataSheetData.get(0).get(0); - String providerAbbreviation = loaderRelatedDataSheetData.get(0).get(1); - String sourceUrl = loaderRelatedDataSheetData.get(0).get(2); - - if (providerName.isEmpty() || providerAbbreviation.isEmpty()) { - stopLoading = true; - - log.error("Missing provider name or abbreviation! Loading process is terminated!"); - return; - } - - ds = dataImportService.getProviderGroup(providerName, providerAbbreviation, "", "", "", sourceUrl); - - } - - /** - * Creates the patient nodes - */ - private void createPatients() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Patients *"); - log.info("******************************************************"); - - for (List<String> patientRow : patientSheetData) { - - String patientId = patientRow.get(0); - String sex = patientRow.get(1); - String cancerHistory = patientRow.get(2); - String ethnicity = patientRow.get(3); - String firstDiagnosis = patientRow.get(4); - String ageAtFirstDiagnosis = patientRow.get(5); - - if (patientId != null && ds != null) { - - Patient patient = dataImportService.createPatient(patientId, ds, sex, "", Standardizer.getEthnicity(ethnicity)); - patient.setCancerRelevantHistory(cancerHistory); - patient.setFirstDiagnosis(firstDiagnosis); - patient.setAgeAtFirstDiagnosis(ageAtFirstDiagnosis); - - dataImportService.savePatient(patient); - - } - } - } - - /** - * Targets an existing patient, creates patient snapshots, patient sample, tumor type and the model - */ - private void createPatientTumors() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Patient samples and snapshots *"); - log.info("******************************************************"); - - int row = 6; - - log.info("Tumor row number: " + patientTumorSheetData.size()); - for (List<String> patientTumorRow : patientTumorSheetData) { - - String patientId = null; - String modelId = null; - String dateOfCollection = null; - String ageAtCollection = null; - String collectionEvent = null; - String elapsedTime = null; - - try { - patientId = patientTumorRow.get(0); - String sampleId = patientTumorRow.get(1); - modelId = patientTumorRow.get(19); - - //skip rows where patient, model or sample id is null - if (patientId == null || sampleId == null || modelId == null) continue; - - dateOfCollection = patientTumorRow.get(2); - collectionEvent = patientTumorRow.get(3); - elapsedTime = patientTumorRow.get(4); - ageAtCollection = patientTumorRow.get(5); - String diagnosis = patientTumorRow.get(6); - String tumorType = patientTumorRow.get(7); - String originTissue = patientTumorRow.get(8); - String collectionSite = patientTumorRow.get(9); - String stage = patientTumorRow.get(10); - String stageClassification = patientTumorRow.get(11); - String grade = patientTumorRow.get(12); - String gradeClassification = patientTumorRow.get(13); - String virologyStatus = patientTumorRow.get(14); - String treatmentNaive = patientTumorRow.get(16); - sampleId = sampleId.trim(); - - if (modelId == null) { - log.error("Missing corresponding Model ID in row " + row); - row++; - continue; - } - - if (dateOfCollection == null && collectionEvent == null && elapsedTime == null && ageAtCollection == null) { - log.error("Missing collection info in row " + row); - row++; - continue; - } - - //hack to avoid 0.0 values and negative numbers - if (elapsedTime != null) { - - elapsedTime = elapsedTime.replaceAll("[^0-9]", ""); - } - - - Patient patient = dataImportService.getPatientWithSnapshots(patientId, ds); - - if (patient == null) { - - log.error("Patient does not exist, can not create tumor for " + patientId); - row++; - continue; - } - - //need this trick to remove float values, ie: patient age = 30.0 - if (ageAtCollection != null && !ageAtCollection.equals("Not Specified")) { - int ageAtColl = (int) Float.parseFloat(ageAtCollection); - ageAtCollection = ageAtColl + ""; - } - - - PatientSnapshot ps = dataImportService.getPatientSnapshot(patient, ageAtCollection, dateOfCollection, collectionEvent, elapsedTime); - ps.setTreatmentNaive(treatmentNaive); - ps.setVirologyStatus(virologyStatus); - - - //have the correct snapshot, create a human sample and link it to the snapshot - tumorType = Standardizer.getTumorType(tumorType); - - - //String sourceSampleId, String dataSource, String typeStr, String diagnosis, String originStr, - //String sampleSiteStr, String extractionMethod, Boolean normalTissue, String stage, String stageClassification, - // String grade, String gradeClassification - Sample sample = dataImportService.getSample(sampleId, ds.getAbbreviation(), tumorType, diagnosis, originTissue, - collectionSite, "", false, stage, stageClassification, grade, gradeClassification); - - ps.addSample(sample); - - - ModelCreation mc = new ModelCreation(); - - mc.setSourcePdxId(modelId); - mc.setDataSource(ds.getAbbreviation()); - mc.setSample(sample); - mc.addRelatedSample(sample); - - patient.addSnapshot(ps); - - dataImportService.savePatient(patient); - dataImportService.savePatientSnapshot(ps); - dataImportService.saveModelCreation(mc); - row++; - - } catch (Exception e) { - log.error("Exception in row: " + row + " for model: " + modelId); - log.error("doc:" + dateOfCollection + " ce:" + collectionEvent + " et:" + elapsedTime + " aac:" + ageAtCollection); - e.printStackTrace(); - - } - - } - - } - - /** - * Targets an existing patient and snapshot to create a treatment summary with treatment protocols - */ - private void createPatientTreatments() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Patient treatments *"); - log.info("******************************************************"); - - int row = 6; - for (List<String> patientTreatmentRow : patientTreatmentSheetData) { - - String patientId = patientTreatmentRow.get(0); - String treatment = patientTreatmentRow.get(1); - String dose = patientTreatmentRow.get(2); - String startingDate = patientTreatmentRow.get(3); - String duration = patientTreatmentRow.get(4); - String response = patientTreatmentRow.get(7); - String responseClassification = patientTreatmentRow.get(8); - - if (patientId.isEmpty() || treatment.isEmpty()) { - - log.error("Empty patient id or treatment in row " + row); - continue; - } - - - Patient patient = dataImportService.findPatient(patientId, ds); - - if (patient == null) { - - log.error("Patient not found: " + patientId); - continue; - } - - PatientSnapshot ps = dataImportService.findLastPatientSnapshot(patientId, ds); - - //at this point a patient should have at least one snapshot, so if ps is null, thats an error - if (ps == null) { - - log.error("No snapshot for patient: " + patientId); - continue; - } - - String treatmentUrl = loaderRelatedDataSheetData.get(0).get(3); - - TreatmentSummary ts = dataImportService.findTreatmentSummaryByPatientSnapshot(ps); - - if (ts == null) { - ts = new TreatmentSummary(); - ts.setUrl(treatmentUrl); - } - - TreatmentProtocol tp = dataImportService.getTreatmentProtocol(treatment, dose, response, responseClassification); - - if (tp != null) { - - //update treatment component type and duration - for (TreatmentComponent tc : tp.getComponents()) { - - tc.setDuration(duration); - //never control on humans! - tc.setType("Drug"); - } - - tp.setTreatmentDate(startingDate); - ts.addTreatmentProtocol(tp); - } - - - ps.setTreatmentSummary(ts); - dataImportService.savePatientSnapshot(ps); - row++; - } - - } - - /** - * Targets an existing model to create specimens with engraftment site, type and material, host strain as well as publication groups - */ - private void createPdxModelDetails() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Model details *"); - log.info("******************************************************"); - - int row = 6; - - for (List<String> modelDetailsRow : pdxModelSheetData) { - - String modelId = modelDetailsRow.get(0); - String hostStrainName = modelDetailsRow.get(1); - String hostStrainNomenclature = modelDetailsRow.get(2); - String engraftmentSite = modelDetailsRow.get(3); - String engraftmentType = modelDetailsRow.get(4); - String engraftmentMaterial = modelDetailsRow.get(5); - String engraftmentMaterialStatus = modelDetailsRow.get(6); - String passage = modelDetailsRow.get(7); - String pubmedIdString = modelDetailsRow.get(8); - - - //check if essential values are not empty - if (modelId.isEmpty() || hostStrainName.isEmpty() || hostStrainNomenclature.isEmpty() || - engraftmentSite.isEmpty() || engraftmentType.isEmpty() || engraftmentMaterial.isEmpty()) { - - log.error("Missing essential value in row: " + row); - row++; - continue; - - } - - //at this point the corresponding pdx model node should be created and linked to a human sample - ModelCreation model = null; - try { - model = dataImportService.findModelByIdAndDataSource(modelId, ds.getAbbreviation()); - - } catch (Exception e) { - log.error("Error with model: " + modelId + " Probably duplicates?"); - e.printStackTrace(); - } - - if (model == null) { - - log.error("Missing model, cannot add details: " + modelId); - row++; - continue; - } - - //CREATING SPECIMENS: engraftment site, type and material - - EngraftmentSite es = dataImportService.getImplantationSite(engraftmentSite); - EngraftmentType et = dataImportService.getImplantationType(engraftmentType); - EngraftmentMaterial em = dataImportService.createEngraftmentMaterial(engraftmentMaterial, engraftmentMaterialStatus); - - HostStrain hostStrain = null; - try { - hostStrain = dataImportService.getHostStrain(hostStrainName, hostStrainNomenclature, "", ""); - } catch (Exception e) { - e.printStackTrace(); - } - - // passage = 1,3,5 - if (passage.contains(",")) { - - String[] passageArr = passage.split(","); - - for (int i = 0; i < passageArr.length; i++) { - - //create specimens with engraftment data - Specimen specimen = new Specimen(); - specimen.setPassage(passageArr[i].trim()); - specimen.setEngraftmentSite(es); - specimen.setEngraftmentType(et); - specimen.setEngraftmentMaterial(em); - specimen.setHostStrain(hostStrain); - - model.addSpecimen(specimen); - } - } - //the passage is a single number - else if (passage.matches("\\d+")) { - - //need this trick to get rid of fractures if there is any - int passageInt = Integer.parseInt(passage); - passage = String.valueOf(passageInt); - - //create specimens with engraftment data - Specimen specimen = new Specimen(); - specimen.setPassage(passage); - specimen.setEngraftmentSite(es); - specimen.setEngraftmentType(et); - specimen.setEngraftmentMaterial(em); - specimen.setHostStrain(hostStrain); - - model.addSpecimen(specimen); - - } else if (passage.matches("[+-]?([0-9]*[.])?[0-9]+")) { - - //need this trick to get rid of fractures if there is any - double passageDouble = Double.parseDouble(passage); - passage = String.valueOf((int)passageDouble); - - //create specimens with engraftment data - Specimen specimen = new Specimen(); - specimen.setPassage(passage); - specimen.setEngraftmentSite(es); - specimen.setEngraftmentType(et); - specimen.setEngraftmentMaterial(em); - specimen.setHostStrain(hostStrain); - - model.addSpecimen(specimen); - } else { - - log.error("Not supported value(" + passage + ") for passage at row " + row); - } - - //CREATE PUBLICATION GROUPS - - //check if pubmed id is in the right format, ie id starts with PMID - if (pubmedIdString != null && !pubmedIdString.isEmpty() && pubmedIdString.toLowerCase().contains("pmid")) { - - // pubmed ids separated with a comma, create multiple groups - if (pubmedIdString.contains(",")) { - - String[] pubmedArr = pubmedIdString.split(","); - - for (int i = 0; i < pubmedArr.length; i++) { - - Group g = dataImportService.getPublicationGroup(pubmedArr[i].trim()); - model.addGroup(g); - } - } - //single publication, create one group only - else { - - Group g = dataImportService.getPublicationGroup(pubmedIdString.trim()); - model.addGroup(g); - } - - } - - dataImportService.saveModelCreation(model); - row++; - } - } - - /** - * Targets existing model to add validation (QA) nodes - */ - private void createPdxModelValidations() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Model validations *"); - log.info("******************************************************"); - - int row = 6; - - for (List<String> pdxModelValidationRow : pdxModelValidationSheetData) { - - String modelId = ""; - String validationTechnique = ""; - String validationDescription = ""; - String passages = ""; - String validationHostStrain = ""; - - try { - modelId = pdxModelValidationRow.get(0); - validationTechnique = pdxModelValidationRow.get(1); - validationDescription = pdxModelValidationRow.get(2); - passages = pdxModelValidationRow.get(3); - validationHostStrain = pdxModelValidationRow.get(4); - } catch (Exception e) { - - log.error("Error in row: " + row); - e.printStackTrace(); - } - - if (modelId.isEmpty() || validationTechnique.isEmpty()) { - - log.error("Empty essential value in row: " + row); - row++; - continue; - } - - - //at this point the corresponding pdx model node should be created and available for lookup - ModelCreation model = dataImportService.findModelByIdAndDataSource(modelId, ds.getAbbreviation()); - - if (model == null) { - - log.error("Missing model, cannot add validation: " + modelId); - row++; - continue; - } - - //need this trick to get rid of 0.0 if there is any - String[] passageArr = passages.split(","); - passages = ""; - - for (int i = 0; i < passageArr.length; i++) { - - String pass; - try { - int passageInt = (int) Float.parseFloat(passageArr[i]); - pass = String.valueOf(passageInt); - } catch (NumberFormatException | NullPointerException nfe) { - - pass = passageArr[i]; - } - - passages += pass + ","; - } - //remove that last comma - passages = passages.substring(0, passages.length() - 1); - - QualityAssurance qa = new QualityAssurance(); - qa.setTechnology(validationTechnique); - qa.setDescription(validationDescription); - qa.setPassages(passages); - - model.addQualityAssurance(qa); - dataImportService.saveModelCreation(model); - - } - } - - /** - * Requirements: - * <p> - * PATIENT - * existing patient sample - * <p> - * XENOGRAFT - * existing model, specimen, creates xeno sample if not present - * <p> - * Creates a molecular characterization with a platform and links it to the appropriate sample - */ - private void createDerivedPatientModelDataset() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating dataset derived from patients and models *"); - log.info("******************************************************"); - - int row = 6; - this.modelIDs = new HashSet<>(); - - for (List<String> derivedDatasetRow : samplePlatformDescriptionSheetData) { - - String sampleId = derivedDatasetRow.get(0); - - String origin = derivedDatasetRow.get(1); - String passage = derivedDatasetRow.get(2); - String engraftedTumorCollectionSite = derivedDatasetRow.get(3); - String modelId = derivedDatasetRow.get(4); - String hostStrainName = derivedDatasetRow.get(5); - - String nomenclature = derivedDatasetRow.get(6); - - String molCharType = derivedDatasetRow.get(7); - String platformName = derivedDatasetRow.get(8); - String platformTechnology = derivedDatasetRow.get(9); - String platformDescription = derivedDatasetRow.get(10); - String analysisProtocol = derivedDatasetRow.get(11); - - String platformUrl = derivedDatasetRow.get(15); - - - if (platformUrl != null) { - platformUrl = platformUrl.replaceAll("[^A-Za-z0-9 /_-]", ""); - } - - - //TODO: get additional fields from the sheet - - //check essential values - - if (sampleId == null || origin == null || modelId == null - || molCharType == null || platformName == null || platformTechnology == null || platformDescription == null - ) { - - log.error("Missing essential value in row " + row); - row++; - continue; - } - - sampleId = sampleId.trim(); - ModelCreation model; - Sample sample; - Platform platform; - - String platformTag = ""; - - switch(molCharType) { - case "mutation" : - platformTag = "_mut"; - break; - case "copy number alteration" : - platformTag = "_cna"; - break; - case "expression" : - platformTag = "_expr"; - break; - default: - break; - } - - - //patient sample - if (origin.toLowerCase().equals("patient")) { - - sample = dataImportService.findHumanSample(modelId, ds.getAbbreviation()); - - if (sample != null) { - - platform = dataImportService.getPlatform(platformName, molCharType, ds); - - if ((platform.getUrl() == null || platform.getUrl().isEmpty()) && platformUrl != null && platformUrl.length() > 3) { - log.info("Saved platform:" + platform.getName() + " Url: " + (platform.getUrl() == null ? "null" : platform.getUrl()) + " Url in file: " + platformUrl); - platform.setUrl(platformUrl); - dataImportService.savePlatform(platform); - log.info("Updating platform url"); - } else { - - log.warn("Platform " + platform.getName()+platformTag + " was not updated. "); - } - - MolecularCharacterization mc = new MolecularCharacterization(); - mc.setPlatform(platform); - mc.setType(molCharType.toLowerCase()); - mc.setTechnology(platformTechnology); - sample.addMolecularCharacterization(mc); - sample.setSourceSampleId(sampleId); - dataImportService.saveSample(sample); - - } else { - - log.error("Unknown human sample with id: " + sampleId); - row++; - continue; - } - - - } - - - //xenograft sample - //specimen should have been created before - else if (origin.toLowerCase().equals("engrafted tumor") || origin.toLowerCase().equals("engrafted tumour") || origin.toLowerCase().equals("xenograft")) { - - if (passage == null || passage.isEmpty() || passage.toLowerCase().equals("not specified")) { - - log.error("Missing essential value Xenograft Passage in row " + row); - row++; - continue; - } - - if (nomenclature == null || nomenclature.isEmpty()) { - - log.error("Missing essential value nomenclature in row " + row); - row++; - continue; - } - - //need this trick to get rid of 0.0 if there is any - //if(passage.equals("0.0")) passage = "0"; - int passageInt = (int) Float.parseFloat(passage); - passage = String.valueOf(passageInt); - - model = dataImportService.findModelByIdAndDataSourceWithSpecimensAndHostStrain(modelId, ds.getAbbreviation()); - - if (model == null) { - log.error("Model " + modelId + " not found, skipping"); - row++; - continue; - } - - //check if targeted specimen is present, if not, create it - Specimen specimen = null; - - for (Specimen sp : model.getSpecimens()) { - //specimen passage and host strain nomenclature are the same - if (sp.getPassage().equals(passage) && sp.getHostStrain().getSymbol().equals(nomenclature)) { - - specimen = sp; - break; - } - } - - //this is a new specimen - if (specimen == null) { - - HostStrain hostStrain = null; - - try { - hostStrain = dataImportService.getHostStrain(hostStrainName, nomenclature, null, null); - } catch (Exception e) { - e.printStackTrace(); - } - - specimen = new Specimen(); - specimen.setPassage(passage); - specimen.setHostStrain(hostStrain); - - Sample s = new Sample(); - s.setSourceSampleId(sampleId); - specimen.setSample(s); - model.addSpecimen(specimen); - - } - - - sample = specimen.getSample(); - - if (sample == null) { - - sample = new Sample(); - sample.setSourceSampleId(sampleId); - - } - - - platform = dataImportService.getPlatform(platformName, molCharType, ds); - - if ((platform.getUrl() == null || platform.getUrl().isEmpty()) && platformUrl != null && platformUrl.length() > 3) { - log.info("Saved platform:" + platform.getName() + " Url: " + (platform.getUrl() == null ? "null" : platform.getUrl()) + " Url in file: " + platformUrl); - platform.setUrl(platformUrl); - dataImportService.savePlatform(platform); - log.info("Updating platform url"); - } - - MolecularCharacterization mc = new MolecularCharacterization(); - mc.setPlatform(platform); - mc.setType(molCharType.toLowerCase()); - mc.setTechnology(platformTechnology); - sample.addMolecularCharacterization(mc); - model.addRelatedSample(sample); - - specimen.setSample(sample); - - model.addSpecimen(specimen); - model.addRelatedSample(sample); - dataImportService.saveModelCreation(model); - dataImportService.saveSpecimen(specimen); - dataImportService.saveSample(sample); - - //log.info(" Specimen with the following details was created: "+modelId+" "+passage+" "+nomenclature+ " in row: "+row); - - - } else { - //origin is not patient nor xenograft - log.error("Unknown sample origin in row " + row); - } - - this.modelIDs.add(modelId); - row++; - } - - } - - - private void createOmicData() { - - log.info("******************************************************"); - log.info("* Loading Omic Data *"); - log.info("******************************************************"); - log.info(this.modelIDs.toString()); - - omicDataSource = ds.getAbbreviation(); - dataSourceAbbreviation = loaderRelatedDataSheetData.get(0).get(1); - finderRootDir = stripTrailingSlash(finderRootDir); - dataRootDirectory = finderRootDir + "/data/UPDOG"; - - omicModelID = "Model_ID"; - omicSampleID = "Sample_ID"; - omicSampleOrigin = "sample_origin"; - omicPassage = "Passage"; - omicHostStrainName = "host_strain_name"; - omicHgncSymbol = "hgnc_symbol"; - omicAminoAcidChange = "amino_acid_change"; - omicNucleotideChange = "nucleotide_change"; - omicConsequence = "consequence"; - omicReadDepth = "read_depth"; - omicAlleleFrequency = "Allele_frequency"; - omicChromosome = "chromosome"; - omicSeqStartPosition = "seq_start_position"; - omicRefAllele = "ref_allele"; - omicAltAllele = "alt_allele"; - omicUcscGeneId = "ucsc_gene_id"; - omicNcbiGeneId = "ncbi_gene_id"; - omicEnsemblGeneId = "ensembl_gene_id"; - omicEnsemblTranscriptId = "ensembl_transcript_id"; - omicRsIdVariants = "rs_id_Variant"; - omicGenomeAssembly = "genome_assembly"; - omicPlatform = "Platform"; - - omicSeqEndPosition = "seq_end_position"; - omicCnaLog10RCNA = "log10R_cna"; - omicCnaLog2RCNA = "log2R_cna"; - omicCnaCopyNumberStatus = "copy_number_status"; - omicCnaGisticvalue = "gistic_value_cna"; - omicCnaPicnicValue = "picnic_value"; - rnaSeqCoverage = "RNAseq_coverage"; - rnaSeqFPKM = "RNAseq_FPKM"; - rnaSeqTPM = "RNAseq_TPM"; - rnaSeqCount = "RNAseq_count"; - affyHGEAProbeId = "affy_HGEA_probeID"; - affyHGEAExpressionValue = "Affy_HGEA_expressionValue"; - illuminaHGEAProbeId = "Illumina_HGEA_probeID"; - illuminaHGEAExpressionValue = "Illumina_HGEA_expressionValue"; - - - - platformURL = new HashMap<>(); - - if (dataSourceAbbreviation.equals("CRL")) { - omicDataFilesType = "ONE_FILE_PER_MODEL"; - omicFileExtension = "csv"; - } - else if(dataSourceAbbreviation.equals("UOM-BC")){ - omicDataFilesType = "ONE_FILE_PER_MODEL"; - omicFileExtension = "xlsx"; - } - else { - omicDataFilesType = "ALL_MODELS_IN_ONE_FILE"; - omicFileExtension = "xlsx"; - } - - - String providerDataRootDir = dataRootDirectory + "/" +dataSourceAbbreviation; - - String mutationDataDir = dataRootDirectory + "/" + dataSourceAbbreviation + "/mut/"; - String cnaDataDir = dataRootDirectory + "/" + dataSourceAbbreviation + "/cna/"; - String transcriptomicDataDir = dataRootDirectory + "/" + dataSourceAbbreviation + "/trans/"; - - File mutationData = new File(mutationDataDir); - File cnaData = new File(cnaDataDir); - File transcriptomicData = new File(transcriptomicDataDir); - - - log.info("Provider data root dir: "+providerDataRootDir); - for (String modelId : this.modelIDs) { - - ModelCreation modelCreation = dataImportService.findBySourcePdxIdAndDataSourceWithSamplesAndSpecimensAndHostStrain(modelId, ds.getAbbreviation()); - - if (modelCreation != null) { - - // Mutation Data Load - if (mutationData.exists()) { - log.info("Loading mutation for " + modelId); - loadOmicData(modelCreation, ds, "mutation", providerDataRootDir); - } - - // Copy Number Alteration Data Load - if (cnaData.exists()) { - log.info("Loading cna for " + modelId); - loadOmicData(modelCreation, ds, "copy number alteration", providerDataRootDir); - } - - // Transcriptomics - if(transcriptomicData.exists()){ - log.info("Loading expression for {}",modelId); - loadOmicData(modelCreation, ds, "expression", providerDataRootDir); - } - - - } else { - - log.error("Cannot load omic data for missing model: " + modelId); - } - - } - - - } - - - /** - * Targets existing model, creates external urls, updates provider type - */ - private void createSharingAndContacts() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating Sharing and contact info *"); - log.info("******************************************************"); - - int row = 6; - - for (List<String> sharingAndContactRow : sharingAndContactSheetData) { - - String modelId = sharingAndContactRow.get(0); - String dataProviderType = sharingAndContactRow.get(1); - String modelAccessibility = sharingAndContactRow.get(2); - String accessModalities = sharingAndContactRow.get(3); - String contactEmail = sharingAndContactRow.get(4); - String contactFormLink = sharingAndContactRow.get(6); - String modelLinkToDB = sharingAndContactRow.get(7); - String providerAbbreviation = sharingAndContactRow.get(9); - String projectName = sharingAndContactRow.get(10); - - if (modelId.isEmpty()) { - - log.error("Model id is empty in row: " + row); - row++; - continue; - } - - if (accessModalities == null) accessModalities = ""; - if (modelAccessibility == null) modelAccessibility = ""; - - //at this point the corresponding pdx model node should be created - - ModelCreation model = dataImportService.findModelByIdAndDataSource(modelId, ds.getAbbreviation()); - - if (model == null) { - - log.error("Missing model, cannot add sharing and contact info: " + modelId); - row++; - continue; - } - - //Add contact provider and view data - List<ExternalUrl> externalUrls = new ArrayList<>(); - if(contactEmail != null && !contactEmail.isEmpty()){ - externalUrls.add(dataImportService.getExternalUrl(ExternalUrl.Type.CONTACT, contactEmail)); - } - - if(contactFormLink != null && !contactFormLink.isEmpty()){ - externalUrls.add(dataImportService.getExternalUrl(ExternalUrl.Type.CONTACT, contactFormLink)); - } - - externalUrls.add(dataImportService.getExternalUrl(ExternalUrl.Type.SOURCE, modelLinkToDB)); - model.setExternalUrls(externalUrls); - - - if (projectName != null && !projectName.isEmpty()) { - - Group project = dataImportService.getProjectGroup(projectName); - model.addGroup(project); - } - - if (modelAccessibility != "" || accessModalities != "") { - - Group access = dataImportService.getAccessibilityGroup(modelAccessibility, accessModalities); - model.addGroup(access); - } - dataImportService.saveModelCreation(model); - - //Update datasource - ds.setProviderType(dataProviderType); - ds.setContact(contactEmail); - - - } - - dataImportService.saveGroup(ds); - - } - - - private void createCytogeneticsData() { - - if (stopLoading) return; - - log.info("******************************************************"); - log.info("* Creating breast and or colorectal markers *"); - log.info("******************************************************"); - - int row = 6; - - Map<String, MolecularCharacterization> existingMolcharNodes = new HashMap<>(); - Map<String, MolecularCharacterization> toBeCreatedMolcharNodes = new HashMap<>(); - - for (List<String> dataRow : cytogeneticsSheetData) { - - String passage = dataRow.get(2); - String modelId = dataRow.get(4); - String origin = dataRow.get(1); - - - if(origin.toLowerCase().equals("xenograft")) { - String pass = passage; - - - try { - int passageInt = (int) Float.parseFloat(pass); - passage = String.valueOf(passageInt); - } catch (NumberFormatException | NullPointerException nfe) { - - log.error("Invalid passage " + passage + " for model:" + modelId); - } - } - else{ - passage = "NA"; - } - - ModelCreation modelCreation = dataImportService.findBySourcePdxIdAndDataSourceWithSamplesAndSpecimensAndHostStrain(modelId, ds.getAbbreviation()); - - if(modelCreation == null){ - log.error("Missing model +"+modelId + " in row "+row); - row++; - continue; - } - - //get all molchars related to patient sample - if(modelCreation.getSample().getMolecularCharacterizations() != null){ - - for(MolecularCharacterization mc : modelCreation.getSample().getMolecularCharacterizations()){ - - if (mc != null && mc.getPlatform() != null){ - - String molcharKey = modelCreation.getSourcePdxId()+ "__"+modelCreation.getSample().getSourceSampleId() + "__" + passage + "__" + mc.getPlatform().getName()+ "__patient__"+mc.getType(); - existingMolcharNodes.put(molcharKey, mc); - } - } - } - - - //then all molchars related to xenograft samples - - if(modelCreation.getSpecimens()!= null){ - - for(Specimen sp: modelCreation.getSpecimens()){ - - Sample sample = sp.getSample(); - - if(sample != null && sample.getMolecularCharacterizations() != null){ - - for(MolecularCharacterization mc: sample.getMolecularCharacterizations()){ - - if(sample.getSourceSampleId() == null ) log.error("Missing sampleid for "+modelId); - if(sp.getPassage() == null) log.error("Missing passage for "+modelId); - if(mc.getPlatform() == null) log.error("Missing platform for "+modelId); - - if(mc.getPlatform().getName() == null) log.error("Missing platform name for "+modelId); - - String molcharKey = modelCreation.getSourcePdxId()+ "__"+ sample.getSourceSampleId() + "__" + sp.getPassage() + "__" + mc.getPlatform().getName()+ "__xenograft__"+mc.getType(); - existingMolcharNodes.put(molcharKey, mc); - } - } - } - } - - row++; - } - - - - //TODO: At some point deal with micro-satelite instability. Currently those rows are skipped. We don't want instability in our lives just yet. - - //first get all markers for the individual molchar objects - MarkerAssociation ma = new MarkerAssociation(); - for (List<String> dataRow : cytogeneticsSheetData) { - - String sampleId = dataRow.get(0); - String origin = dataRow.get(1); - String passage = dataRow.get(2); - String nomenclature = dataRow.get(3); - String modelId = dataRow.get(4); - String markerSymbol = dataRow.get(5); - String markerStatus = dataRow.get(6); - String technique = dataRow.get(8); - String platform = dataRow.get(9); - String characterizationType = "Unknown"; - - - - if (origin == null || modelId == null || markerSymbol == null || markerStatus == null || technique == null) { - log.error("Missing essential value in row " + row); - row++; - continue; - } - - if(origin.toLowerCase().equals("xenograft")) { - String pass = passage; - - try { - int passageInt = (int) Float.parseFloat(pass); - passage = String.valueOf(passageInt); - } catch (NumberFormatException | NullPointerException nfe) { - - log.error("Invalid passage "+passage +" for model:"+modelId); - } - } - else{ - - passage = "NA"; - } - - - MolecularCharacterization mc; - Platform pl; - Marker marker = null; - - if (technique.toLowerCase().equals("immunohistochemistry") || technique.toLowerCase().equals("fish")) { - characterizationType = "cytogenetics"; - } - - NodeSuggestionDTO nsdto = dataImportService.getSuggestedMarker(this.getClass().getSimpleName(), ds.getAbbreviation(), modelId, markerSymbol, characterizationType, technique); - - if (nsdto.getNode() == null) { - - //uh oh, we found an unrecognised marker symbol, abort, abort!!!! - reportManager.addMessage(nsdto.getLogEntity()); - continue; - } else { - - marker = (Marker) nsdto.getNode(); - - MolecularCharacterization molecularCharacterization; - - String molcharKey = modelId + "__"+ sampleId + "__" + passage + "__" + technique + "__" +origin.toLowerCase() + "__cytogenetics"; - - if(existingMolcharNodes.containsKey(molcharKey)){ - molecularCharacterization = existingMolcharNodes.get(molcharKey); - } - else if(toBeCreatedMolcharNodes.containsKey(molcharKey)){ - molecularCharacterization = toBeCreatedMolcharNodes.get(molcharKey); - } - else{ - log.info("Looking at molchar "+molcharKey); - //log.info("Existing keys: "); - //log.info(existingMolcharNodes.keySet().toString()); - molecularCharacterization = new MolecularCharacterization(); - molecularCharacterization.setType("cytogenetics"); - molecularCharacterization.setPlatform(dataImportService.getPlatform(technique,"cytogenetics", ds)); - toBeCreatedMolcharNodes.put(molcharKey, molecularCharacterization); - } - - MolecularData md = new MolecularData(); - md.setMarker(marker.getHgncSymbol()); - - - if (technique.toLowerCase().equals("immunohistochemistry") || technique.toLowerCase().equals("fish")) { - - md.setCytogeneticsResult(markerStatus); - } - //what if it is not ihc? - - molecularCharacterization.addMarkerAssociation(ma); - - } - - - row++; - } - - - //get the corresponding samples for the molchar objects, link them and save them. - for(Map.Entry<String, MolecularCharacterization> mcEntry : existingMolcharNodes.entrySet()){ - - dataImportService.saveMolecularCharacterization(mcEntry.getValue()); - } - - - //PHASE 3: get objects from cache and persist them - for(Map.Entry<String, MolecularCharacterization> mcEntry : toBeCreatedMolcharNodes.entrySet()){ - - String mcKey = mcEntry.getKey(); - MolecularCharacterization mc = mcEntry.getValue(); - - String[] mcKeyArr = mcKey.split("__"); - //String molcharKey = modelId + "__"+ sampleId + "__" + passage + "__" + technique + "__" +origin.toLowerCase() + "__cytogenetics"; - String modelId = mcKeyArr[0]; - String sampleId = mcKeyArr[1]; - String pass = getPassage(mcKeyArr[2]); - String sampleOrigin = mcKeyArr[4]; - - ModelCreation modelCreation = dataImportService.findBySourcePdxIdAndDataSourceWithSamplesAndSpecimensAndHostStrain(modelId, ds.getAbbreviation()); - - if(modelCreation == null){ - log.error("Missing model: "+modelId); - continue; - } - - boolean foundSpecimen = false; - - if(sampleOrigin.toLowerCase().equals("patient")){ - - Sample patientSample = modelCreation.getSample(); - patientSample.setSourceSampleId(sampleId); - patientSample.addMolecularCharacterization(mc); - - } - //xenograft - else if(sampleOrigin.toLowerCase().equals("xenograft")){ - - if(modelCreation.getSpecimens() != null){ - - for(Specimen specimen : modelCreation.getSpecimens()){ - - if(specimen.getPassage().equals(pass)){ - - if(specimen.getSample() != null && specimen.getSample().getSourceSampleId().equals(sampleId)){ - - Sample xenograftSample = specimen.getSample(); - xenograftSample.addMolecularCharacterization(mc); - - foundSpecimen = true; - } - } - } - } - - - //this passage is either not present yet or the linked sample has a different ID, create a specimen with sample and link mc - if(!foundSpecimen){ - log.info("Creating new specimen for "+mcKey); - - Sample xenograftSample = new Sample(); - xenograftSample.setSourceSampleId(sampleId); - xenograftSample.addMolecularCharacterization(mc); - - Specimen specimen = new Specimen(); - specimen.setPassage(pass); - specimen.setSample(xenograftSample); - - - modelCreation.addRelatedSample(xenograftSample); - modelCreation.addSpecimen(specimen); - } - - - } - - - - dataImportService.saveModelCreation(modelCreation); - - - - } - - log.info("******************************************************"); - log.info("* Finished creating breast and or colorectal markers *"); - log.info("******************************************************"); - - } - - /** - * Checks if a list consists of nulls only - * - * @param list - */ - boolean isRowOfNulls(List list) { - for (Object o : list) - if (!(o == null)) - return false; - return true; - } - - - private String getMolcharType(String technique) { - - if (technique.toLowerCase().equals("immunohistochemistry")) { - return "cytogenetics"; - } else if (technique.toLowerCase().equals("fish")) { - return "cytogenetics"; - } - - return null; - } - - public static String stripTrailingSlash(String filePath) { - return filePath.endsWith("/") ? - filePath.replaceFirst("/$", "") : - filePath; - } - - - public List<List<String>> getPatientSheetData() { - return patientSheetData; - } - - public List<List<String>> getPatientTumorSheetData() { - return patientTumorSheetData; - } - - public List<List<String>> getPatientTreatmentSheetData() { - return patientTreatmentSheetData; - } - - public List<List<String>> getPdxModelSheetData() { - return pdxModelSheetData; - } - - public List<List<String>> getPdxModelValidationSheetData() { - return pdxModelValidationSheetData; - } - - public List<List<String>> getSamplePlatformDescriptionSheetData() { - return samplePlatformDescriptionSheetData; - } - - public List<List<String>> getSharingAndContactSheetData() { - return sharingAndContactSheetData; - } - - public List<List<String>> getCytogeneticsSheetData() { - return cytogeneticsSheetData; - } - - public List<List<String>> getLoaderRelatedDataSheetData() { - return loaderRelatedDataSheetData; - } - - public String getFinderRootDir() { - return finderRootDir; - } - - public void setFinderRootDir(String finderRootDir) { - this.finderRootDir = finderRootDir; - } -} \ No newline at end of file diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Reader.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Reader.java index 060b050eeefd6d4af8b62a9df34ddeed75e0d20e..f474fc2d7727a06fd9922947c9478db0ea7f0feb 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Reader.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Reader.java @@ -1,13 +1,15 @@ package org.pdxfinder.dataloaders.updog; -import org.springframework.stereotype.Component; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import tech.tablesaw.api.Table; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -21,7 +23,6 @@ public class Reader { Map<String, Table> readAllTsvFilesIn(Path targetDirectory, PathMatcher filter) { HashMap<String, Table> tables = new HashMap<>(); - try (final Stream<Path> stream = Files.list(targetDirectory)) { stream .filter(filter::matches) diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableSetUtilities.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableSetUtilities.java index 6ca0e1a772b7bb47ff95f68126ff11f79154255f..433a86df2c330b952350953134e2680ef4d5f8c8 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableSetUtilities.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableSetUtilities.java @@ -1,16 +1,10 @@ package org.pdxfinder.dataloaders.updog; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.poi.util.StringUtil; import tech.tablesaw.api.Table; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import java.util.*; +import java.util.stream.*; public class TableSetUtilities { diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableUtilities.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableUtilities.java index 5e3d711a9daecfe17c93a71eb66d354ea733fe8f..4f1027fa9daaaf91e3e3e77101852693077440d8 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableUtilities.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/TableUtilities.java @@ -8,7 +8,8 @@ import tech.tablesaw.api.Table; import tech.tablesaw.io.csv.CsvReadOptions; import tech.tablesaw.selection.Selection; -import java.io.*; +import java.io.File; +import java.io.IOException; public final class TableUtilities { diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Updog.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Updog.java index 03b0aff79de585c9fea19a00cf0a7d1ff21d9814..2c98e1570806759c5227b2b198c4e891526a012d 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Updog.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/Updog.java @@ -3,14 +3,18 @@ package org.pdxfinder.dataloaders.updog; import org.pdxfinder.dataloaders.updog.domainobjectcreation.DomainObjectCreator; import org.pdxfinder.dataloaders.updog.tablevalidation.*; import org.pdxfinder.dataloaders.updog.tablevalidation.error.ValidationError; -import org.slf4j.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import tech.tablesaw.api.Table; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.PathMatcher; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; @Component public class Updog { diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/DomainObjectCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/DomainObjectCreator.java index eb82f5a06bc4029c8d6978c903f308de55745384..8afb5b9727526a1b79515c7bdc367a8a7247c6c9 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/DomainObjectCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/DomainObjectCreator.java @@ -1,8 +1,8 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; import org.apache.commons.lang3.StringUtils; +import org.pdxfinder.TSV; import org.pdxfinder.dataloaders.updog.Reader; -import org.pdxfinder.dataloaders.updog.TSV; import org.pdxfinder.dataloaders.updog.TableSetCleaner; import org.pdxfinder.graph.dao.*; import org.pdxfinder.services.DataImportService; @@ -977,12 +977,6 @@ public class DomainObjectCreator { log.error("Exception with key "+sampleKey); } } - private void encodeMolecularDataFor(MolecularCharacterization mc) { - if (mc.hasMarkerAssociations()) { - mc.setMarkers(getMarkers(mc.getFirstMarkerAssociation())); - mc.getFirstMarkerAssociation().encodeMolecularData(); - } - } private void encodeMolecularDataFor(MolecularCharacterization mc, String sampleKey) { if (mc.hasMarkerAssociations()) { diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/GroupCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/GroupCreator.java index 41ba0ea1c8c20d34a8e265840a5d2095132974c4..bd9fac5457ae624180c7160becf078731a84ebcd 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/GroupCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/GroupCreator.java @@ -1,6 +1,6 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.pdxfinder.dataloaders.updog.TSV; +import org.pdxfinder.TSV; import org.pdxfinder.graph.dao.Group; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreator.java index d523ce6ddc7ae47a39f0b91ee9bf156d1689110c..149fe7012cce08a3c0744198fd200916a61711e5 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreator.java @@ -1,6 +1,6 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.pdxfinder.dataloaders.updog.TSV; +import org.pdxfinder.TSV; import org.pdxfinder.graph.dao.Group; import org.pdxfinder.graph.dao.ModelCreation; import org.pdxfinder.graph.dao.Sample; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/PatientCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/PatientCreator.java index 86bfd0e5abe6b34a10fe3ece95f1a5e072f3ff34..bd62c310adcc8cf38dd4ab467bea85bff2845fc7 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/PatientCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/PatientCreator.java @@ -1,6 +1,6 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.pdxfinder.dataloaders.updog.TSV; +import org.pdxfinder.TSV; import org.pdxfinder.graph.dao.Group; import org.pdxfinder.graph.dao.Patient; import org.slf4j.Logger; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreator.java index 9bf98778e60917ff8220259e1bfbf6bd4ecf48a3..3e907f6d3e191728d9ffad599dd27d1b23fb9ae8 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreator.java @@ -1,6 +1,6 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.pdxfinder.dataloaders.updog.TSV; +import org.pdxfinder.TSV; import org.pdxfinder.graph.dao.Sample; import org.pdxfinder.graph.dao.Tissue; import org.pdxfinder.graph.dao.TumorType; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreator.java index 8b0b664d9e6f087f9b4306f5e79d8ae29c244844..00fc22e67529aeecc8a9b666b246e9438e14ffd2 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreator.java @@ -1,12 +1,7 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.pdxfinder.dataloaders.updog.TSV; -import org.pdxfinder.graph.dao.EngraftmentMaterial; -import org.pdxfinder.graph.dao.EngraftmentSite; -import org.pdxfinder.graph.dao.EngraftmentType; -import org.pdxfinder.graph.dao.HostStrain; -import org.pdxfinder.graph.dao.Sample; -import org.pdxfinder.graph.dao.Specimen; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporter.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporter.java index 1e016d1a47578fc6e99d0a38b7dacf5744c1edfc..d5938f16539f8948cde39c1019592c79fcee42bc 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporter.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporter.java @@ -2,9 +2,10 @@ package org.pdxfinder.dataloaders.updog.tablevalidation; import org.apache.commons.collections4.CollectionUtils; import org.pdxfinder.dataloaders.updog.tablevalidation.error.ValidationError; -import org.slf4j.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.List; public class ErrorReporter { diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/Validator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/Validator.java index 4225a06fdfc61b70e38eded906847dfd81b6a4a1..c341bbcf2f5c1122a1f6a84757cc45a727335ec3 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/Validator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/Validator.java @@ -2,11 +2,14 @@ package org.pdxfinder.dataloaders.updog.tablevalidation; import org.apache.commons.collections4.CollectionUtils; import org.pdxfinder.dataloaders.updog.tablevalidation.error.*; -import org.slf4j.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import tech.tablesaw.api.Table; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; @Component public class Validator { @@ -27,14 +30,7 @@ public class Validator { TableSetSpecification tableSetSpecification ) { checkRequiredTablesPresent(tableSet, tableSetSpecification); - if (CollectionUtils.isNotEmpty(validationErrors)) { - log.error( - "Not all required tables where present for {}. Aborting further validation", - tableSetSpecification.getProvider()); - return validationErrors; - } performColumnValidations(tableSet, tableSetSpecification); - return validationErrors; } @@ -42,12 +38,25 @@ public class Validator { Map<String, Table> tableSet, TableSetSpecification tableSetSpecification ) { + if (thereAreErrors(validationErrors, tableSetSpecification)) return; checkRequiredColumnsPresent(tableSet, tableSetSpecification); checkAllNonEmptyValuesPresent(tableSet, tableSetSpecification); checkAllUniqueColumnsForDuplicates(tableSet, tableSetSpecification); checkRelationsValid(tableSet, tableSetSpecification); } + private boolean thereAreErrors( + List<ValidationError> validationErrors, + TableSetSpecification tableSetSpecification + ) { + if (CollectionUtils.isNotEmpty(validationErrors)) { + log.error( + "Not all required tables where present for {}. Aborting further validation", + tableSetSpecification.getProvider()); + } + return CollectionUtils.isNotEmpty(validationErrors); + } + private void checkRequiredTablesPresent( Map<String, Table> tableSet, TableSetSpecification tableSetSpecification @@ -96,4 +105,13 @@ public class Validator { return this.validationErrors; } + public static void reportAnyErrors(List<ValidationError> validationErrors) { + if (CollectionUtils.isNotEmpty(validationErrors)) + for (ValidationError error : validationErrors) { + log.error(error.message()); + } + else + log.info("There were no validation errors raised, great!"); + } + } diff --git a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreator.java b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreator.java index 1d0e833df47f796495547f8375ca5be6f3ef4d46..8d553db41ab3c2d682470268eef1afe60e8cfa61 100644 --- a/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreator.java +++ b/indexer/src/main/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreator.java @@ -113,20 +113,20 @@ public class BrokenRelationErrorCreator extends ErrorCreator { private boolean missingLeftColumn(Map<String, Table> tableSet, Relation relation) { return tableMissingColumn( tableSet.get(relation.leftTable()), - relation.leftColumn()); + relation.leftColumn(), relation.leftTable()); } private boolean missingRightColumn(Map<String, Table> tableSet, Relation relation) { return tableMissingColumn( tableSet.get(relation.rightTable()), - relation.rightColumn()); + relation.rightColumn(), relation.rightTable()); } - private boolean tableMissingColumn(Table table, String columnName) { + private boolean tableMissingColumn(Table table, String columnName, String tableName) { try { return !table.columnNames().contains(columnName); } catch (NullPointerException e) { - log.error("Couldn't access table {} {}", e, table); + log.error("Couldn't access table {} because of {}",tableName, e.toString()); return true; } } diff --git a/indexer/src/main/java/org/pdxfinder/mapping/LinkSamplesToNCITTerms.java b/indexer/src/main/java/org/pdxfinder/mapping/LinkSamplesToNCITTerms.java index 833dcef72e8aed30b8c756e36d770f0209b2a8c7..21eb599e45cf60ce34222c10ae05b3b5b9a83851 100644 --- a/indexer/src/main/java/org/pdxfinder/mapping/LinkSamplesToNCITTerms.java +++ b/indexer/src/main/java/org/pdxfinder/mapping/LinkSamplesToNCITTerms.java @@ -119,9 +119,7 @@ public class LinkSamplesToNCITTerms { //log.info("Mapping "+diagnosis+" to "+mappingRule.getOntologyTerm()); } } - } - startNode += batchSize; } diff --git a/indexer/src/main/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTerms.java b/indexer/src/main/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTerms.java index 6ea833f0c3ae0a13ed8c3f11f58b9e7a624ce085..57c587697401a3b8dfddd749d467f28aa1e565d8 100644 --- a/indexer/src/main/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTerms.java +++ b/indexer/src/main/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTerms.java @@ -11,8 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.util.Collection; -import java.util.List; +import java.util.*; /* * Created by csaba on 05/06/2019. @@ -109,43 +108,32 @@ public class LinkTreatmentsToNCITTerms { } - private void addRelationshipToTreatments(Collection<Treatment> treatments, String dataSource){ + public void addRelationshipToTreatments(Collection<Treatment> treatments, String dataSource){ + List<String> missingOntologyTerms = new ArrayList<>(); for(Treatment treatment : treatments){ - MappingEntity me = mappingService.getTreatmentMapping(dataSource, treatment.getName()); - if(me == null){ - //TODO: deal with missing mapping rules here log.warn("No mapping rule found for "+dataSource+" "+treatment.getName()); - mappingService.saveUnmappedTreatment(dataSource, treatment.getName()); } else{ - - - OntologyTerm ot = dataImportService.findOntologyTermByUrl(me.getMappedTermUrl()); - - if(ot == null){ - - - log.error("Ontology term not found "+me.getMappedTermUrl()); - } - else{ - + OntologyTerm ontologyTerm = dataImportService.findOntologyTermByUrl(me.getMappedTermUrl()); + if (Objects.isNull(ontologyTerm)) { + missingOntologyTerms.add(me.getMappedTermLabel()); + } else { TreatmentToOntologyRelationship r = new TreatmentToOntologyRelationship(); r.setType(me.getMapType()); r.setJustification(me.getJustification()); - r.setOntologyTerm(ot); + r.setOntologyTerm(ontologyTerm); r.setTreatment(treatment); - - treatment.setTreatmentToOntologyRelationship(r); dataImportService.saveTreatment(treatment); } } } + log.error("Failed to find {} ontology terms: {}", missingOntologyTerms.size(), missingOntologyTerms); } diff --git a/indexer/src/main/java/org/pdxfinder/postload/CreateDataProjections.java b/indexer/src/main/java/org/pdxfinder/postload/CreateDataProjections.java index 3cf183501198140787b770e0a265d5a4a293fb4c..4ed52aa836a4aaf922339aa9703f1f8474b71229 100644 --- a/indexer/src/main/java/org/pdxfinder/postload/CreateDataProjections.java +++ b/indexer/src/main/java/org/pdxfinder/postload/CreateDataProjections.java @@ -1,18 +1,13 @@ package org.pdxfinder.postload; -import com.google.gson.Gson; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.dataloaders.UniversalLoader; +import com.github.openjson.*; import org.pdxfinder.graph.dao.*; import org.pdxfinder.graph.queryresults.MutatedMarkerData; import org.pdxfinder.reportmanager.ReportManager; import org.pdxfinder.services.DataImportService; import org.pdxfinder.services.DrugService; -import org.pdxfinder.services.UtilityService; import org.pdxfinder.services.ds.ModelForQuery; import org.pdxfinder.services.dto.DataAvailableDTO; -import org.pdxfinder.services.dto.NodeSuggestionDTO; -import org.pdxfinder.services.reporting.MarkerLogEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -21,13 +16,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.Order; - import org.springframework.stereotype.Service; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @@ -42,8 +31,6 @@ public class CreateDataProjections implements ApplicationContextAware{ private DataImportService dataImportService; private DrugService drugService; - private UtilityService utilityService; - @Value("${user.home}") String homeDir; @@ -60,9 +47,6 @@ public class CreateDataProjections implements ApplicationContextAware{ private List<ModelForQuery> modelForQueryDP = new ArrayList<>(); - //"platform"=>"marker"=>"set of model ids" - private Map<String, Map<String, Set<Long>>> wtMarkersDataProjection = new HashMap<>(); - //"drugname"=>"response"=>"set of model ids" private Map<String, Map<String, Set<Long>>> modelDrugResponseDP = new HashMap<>(); @@ -92,11 +76,10 @@ public class CreateDataProjections implements ApplicationContextAware{ protected static ApplicationContext context; @Autowired - public CreateDataProjections(DataImportService dataImportService, DrugService drugService, UtilityService utilityService) { + public CreateDataProjections(DataImportService dataImportService, DrugService drugService) { this.dataImportService = dataImportService; this.drugService = drugService; - this.utilityService = utilityService; } public void run() { @@ -524,133 +507,6 @@ public class CreateDataProjections implements ApplicationContextAware{ } - private void addCharlesRiverCNA() throws Exception { - - log.info("Loading additional datasets for CRL."); - - String templateFileStr = finderRootDir + "/data/UPDOG/CRL/metadata.xlsx"; - String markerTemplateFileStr = finderRootDir + "/data/UPDOG/CRL/cna_tested_markers/list.csv"; - - File markerListFile = new File(markerTemplateFileStr); - File templateFile = new File(templateFileStr); - - Set<Marker> markerSet = new HashSet<>(); - - if (markerListFile.exists() && templateFile.exists()) { - - List<List<String>> markerList = utilityService.serializeCSVToArrayList(markerTemplateFileStr); - - //STEP1: get the marker symbols from the csv file then find the corresponding marker node and add it to a set - log.info("Found " + markerList.size() + " markers in the marker file."); - for (int i = 1; i < markerList.size(); i++) { - - if (i % 500 == 0) { - log.info("Collected " + i + " markers from the repository."); - } - - String markerSymbol = markerList.get(i).get(0); - - //skip all symbols with dot in them - if (markerSymbol.contains(".")) { - - MarkerLogEntity le = new MarkerLogEntity(this.getClass().getSimpleName(), "CRL", "-", "copy number alteration", "Not Specified", markerSymbol, "", ""); - le.setMessage(markerSymbol + " is an unrecognised symbol"); - le.setType("ERROR"); - continue; - - } - - - //log.info("Looking up: "+markerSymbol); - NodeSuggestionDTO nsdto = dataImportService.getSuggestedMarker(this.getClass().getSimpleName(), "CRL", "-", markerSymbol, "copy number alteration", "Not Specified"); - - if (nsdto.getNode() == null) { - - //uh oh, we found an unrecognised marker symbol, abort, abort!!!! - reportManager.addMessage(nsdto.getLogEntity()); - - continue; - } else { - - Marker marker = (Marker) nsdto.getNode(); - markerSet.add(marker); - - } - - } - - - //STEP2: - - Set<Long> modelIdSet = new HashSet<>(); - - UniversalLoader updog = new UniversalLoader(reportManager, utilityService, dataImportService); - updog.setFinderRootDir(finderRootDir); - - updog.initTemplates(templateFileStr); - - List<List<String>> datasetDerived = updog.getSamplePlatformDescriptionSheetData(); - int row = 6; - - for (List<String> derivedDatasetRow : datasetDerived) { - - String sampleId = derivedDatasetRow.get(0); - - String origin = derivedDatasetRow.get(1); - String passage = derivedDatasetRow.get(2); - String nomenclature = derivedDatasetRow.get(3); - String modelId = derivedDatasetRow.get(4); - String molCharType = derivedDatasetRow.get(5); - String platformName = derivedDatasetRow.get(6); - String platformTechnology = derivedDatasetRow.get(7); - String platformDescription = derivedDatasetRow.get(8); - String analysisProtocol = derivedDatasetRow.get(9); - - //SKIP everything that is not cna - if (!molCharType.toLowerCase().equals("copy number alteration")) { - - row++; - continue; - } - - - ModelCreation modelCreation = dataImportService.findModelByIdAndDataSource(modelId, "CRL"); - - if(modelCreation != null){ - - modelIdSet.add(modelCreation.getId()); - } - else{ - log.error("Not found model: "+modelId); - } - - - } - - - //STEP3: save the same markers for all models - - for(Marker m: markerSet){ - if(copyNumberAlterationDP.containsKey(m.getHgncSymbol())){ - - copyNumberAlterationDP.get(m.getHgncSymbol()).addAll(modelIdSet); - } - else{ - - copyNumberAlterationDP.put(m.getHgncSymbol(), modelIdSet); - } - - } - - - log.info("DONE faking CNA data for CRL."); - - } - else{ - log.error("Missing files for creating CRL CNA projection."); - } - } - private void addToOneParamDP(Map<String, Set<Long>> collection, String key, Long modelId){ if(key == null || key.isEmpty()) return; @@ -659,7 +515,6 @@ public class CreateDataProjections implements ApplicationContextAware{ collection.get(key).add(modelId); } else{ - Set<Long> s = new HashSet(); s.add(modelId); collection.put(key, s); @@ -670,138 +525,51 @@ public class CreateDataProjections implements ApplicationContextAware{ private void addToTwoParamDP(Map<String, Map<String, Set<Long>>> collection, String key1, String key2, Long modelId){ if(collection.containsKey(key1)){ - if(collection.get(key1).containsKey(key2)){ collection.get(key1).get(key2).add(modelId); - } else{ - Set<Long> set = new HashSet<>(); set.add(modelId); collection.get(key1).put(key2, set); } } else{ - Set<Long> set = new HashSet<>(); set.add(modelId); - Map<String, Set<Long>> map = new HashMap<>(); map.put(key2, set); - collection.put(key1, map); } - } private void addToThreeParamDP(Map<String, Map<String, Map<String, Set<Long>>>> collection, String key1, String key2, String key3, Long modelId){ if(collection.containsKey(key1)){ - if(collection.get(key1).containsKey(key2)){ - if(collection.get(key1).get(key2).containsKey(key3)){ - collection.get(key1).get(key2).get(key3).add(modelId); } else{ - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); collection.get(key1).get(key2).put(key3,models); } - } else{ - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - Map<String, Set<Long>> map3 = new HashMap(); map3.put(key3,models); - collection.get(key1).put(key2, map3); - } - - - } else{ Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - Map<String, Set<Long>> map3 = new HashMap(); map3.put(key3,models); - - Map map2 = new HashMap(); - map2.put(key2, map3); - - collection.put(key1, map2); - } - - - } - - private void addToFourParamDP(Map<String, Map<String, Map<String, Map<String, Set<Long>>>>> collection, String key1, String key2, String key3, String key4, Long modelId){ - - if(collection.containsKey(key1)){ - - if(collection.get(key1).containsKey(key2)){ - - if(collection.get(key1).get(key2).containsKey(key3)){ - - if(collection.get(key1).get(key2).get(key3).containsKey(key4)){ - - collection.get(key1).get(key2).get(key3).get(key4).add(modelId); - } - else{ - - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - - collection.get(key1).get(key2).get(key3).put(key4, models); - } - - } - else{ - - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - - Map<String, Set<Long>> map4 = new HashMap(); - map4.put(key4, models); - - collection.get(key1).get(key2).put(key3, map4); - } - - } - else{ - - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - - Map<String, Set<Long>> map4 = new HashMap(); - map4.put(key4, models); - - Map map3 = new HashMap(); - map3.put(key3, map4); - - collection.get(key1).put(key2, map3); - } - - - } - else{ - - Set<Long> models = new HashSet<>(Arrays.asList(modelId)); - - Map<String, Set<Long>> map4 = new HashMap(); - map4.put(key4, models); - - Map map3 = new HashMap(); - map3.put(key3, map4); - Map map2 = new HashMap(); map2.put(key2, map3); - collection.put(key1, map2); } @@ -917,30 +685,6 @@ public class CreateDataProjections implements ApplicationContextAware{ } - - /* - if (!mutationPlatformsByModel.containsKey(mc.getId())) { - mutationPlatformsByModel.put(mc.getId(), new ArrayList<>()); - } - // Are there any molecular characterizations associated to this model? - if (mc.getRelatedSamples().stream().map(Sample::getMolecularCharacterizations).mapToLong(Collection::size).sum() > 0) { - // Get all molecular characterizations platforms into a list - mutationPlatformsByModel.get(mc.getId()).addAll( - mc.getRelatedSamples().stream() - .map(Sample::getMolecularCharacterizations) - .flatMap(Collection::stream) - .map(x -> { - if (dataImportService.countMarkerAssociationBySourcePdxId(mc.getSourcePdxId(), x.getPlatform().getName()) != 0) { - return x.getPlatform().getName(); - } else { - return " "; - } - }) - .distinct() - .collect(Collectors.toList())); - } - */ - } Map<String, String> cancerSystemMap = new HashMap<>(); @@ -1097,7 +841,7 @@ public class CreateDataProjections implements ApplicationContextAware{ // Add all top level systems (translated) to the Model for (String s : allOntologyTerms.stream().map(OntologyTerm::getLabel).collect(Collectors.toSet())) { - if (cancerSystemMap.keySet().contains(s)) { + if (cancerSystemMap.containsKey(s)) { if (mfq.getCancerSystem() == null) { mfq.setCancerSystem(new ArrayList<>()); @@ -1168,11 +912,8 @@ public class CreateDataProjections implements ApplicationContextAware{ mfqDP.setLabel("ModelForQuery"); } - //log.info("MFQ value toString:"+modelForQueryDP.toString()); - Gson gson = new Gson(); - String jsonMfqDP = gson.toJson(this.modelForQueryDP); + String jsonMfqDP = JSONObject.wrap(modelForQueryDP).toString(); mfqDP.setValue(jsonMfqDP); - //log.info("MFQ value:"+jsonMfqDP); dataImportService.saveDataProjection(mfqDP); @@ -1210,65 +951,56 @@ public class CreateDataProjections implements ApplicationContextAware{ private void createModelDrugResponseDataProjection(){ - log.info("Creating Model Drug Response DP"); + log.info("Creating Model Drug Response Data Projection"); List<TreatmentSummary> treatmentSummaries = drugService.getModelTreatmentSummariesWithDrugAndResponse(); for(TreatmentSummary ts : treatmentSummaries){ - ModelCreation model = dataImportService.findModelByTreatmentSummary(ts); - //check if treatment is linked to a model if(model != null){ - Long modelId = model.getId(); + processModelDrugs(modelId, ts); + } + } + } - for(TreatmentProtocol tp : ts.getTreatmentProtocols()){ - - //this bit adds the drugA + drugB + drugC etc to the options - String drugName = tp.getTreatmentString(true); - String response = tp.getResponse().getDescription(); - addToModelDrugResponseDP(modelId, drugName, response); - - - //we also need to deal with regimens - List<String> regimenDrugs = new ArrayList<>(); - for(TreatmentComponent tc: tp.getComponents()){ - - Treatment t = tc.getTreatment(); - OntologyTerm ot = t.getTreatmentToOntologyRelationship().getOntologyTerm(); - - if(ot.getType().equals("treatment regimen") && ot.getSubclassOf() != null && !ot.getSubclassOf().isEmpty()){ - - - - for(OntologyTerm ot2: ot.getSubclassOf()){ + public void processModelDrugs(Long modelId, TreatmentSummary ts){ - regimenDrugs.add(ot2.getLabel()); + for(TreatmentProtocol tp : ts.getTreatmentProtocols()){ + //this bit adds the drugA + drugB + drugC etc to the options + String drugName = tp.getTreatmentString(true); + String response = tp.getResponse().getDescription(); + addToModelDrugResponseDP(modelId, drugName, response); - } - - } - } + processModelRegimens(modelId, tp, response); + } + } - //sort them alphabetically - if(regimenDrugs.size() != 0){ - Collections.sort(regimenDrugs); - drugName = String.join(" and ", regimenDrugs); - addToModelDrugResponseDP(modelId, drugName, response); - } + public void processModelRegimens(Long modelId, TreatmentProtocol tp, String response){ + List<String> regimenDrugs = new ArrayList<>(); + for(TreatmentComponent tc: tp.getComponents()){ + Treatment t = tc.getTreatment(); + OntologyTerm ot = t.getTreatmentToOntologyRelationship().getOntologyTerm(); + if(ot.getType().equals("treatment regimen") && ot.getSubclassOf() != null && !ot.getSubclassOf().isEmpty()){ + for(OntologyTerm ot2: ot.getSubclassOf()){ + regimenDrugs.add(ot2.getLabel()); } } } - System.out.println(); + //sort them alphabetically + if(regimenDrugs.size() != 0){ + Collections.sort(regimenDrugs); + String drugName = String.join(" and ", regimenDrugs); + addToModelDrugResponseDP(modelId, drugName, response); + } } - private void createPatientTreatmentDataProjection(){ - log.info("Creating patient treatment DP"); + log.info("Creating patient treatment data projection"); List<TreatmentSummary> treatmentSummaries = drugService.getPatientTreatmentSummariesWithDrug(); @@ -1346,7 +1078,7 @@ public class CreateDataProjections implements ApplicationContextAware{ private void createFrequentlyMutatedGenesDataProjection(){ - log.info("Creating Frequently Mutated Genes DP"); + log.info("Creating Frequently Mutated Genes data projection"); for(Map.Entry<String, Set<Long>> entry : frequentlyMutatedMarkers.entrySet() ){ @@ -1423,251 +1155,147 @@ public class CreateDataProjections implements ApplicationContextAware{ drugDosingDP.get(drug).add(modelId); } - private void saveDataProjections(){ + public void saveDataProjections(){ log.info("Saving DataProjections"); - DataProjection pmvmDP = dataImportService.findDataProjectionByLabel("PlatformMarkerVariantModel"); - - if (pmvmDP == null){ - - pmvmDP = new DataProjection(); - pmvmDP.setLabel("PlatformMarkerVariantModel"); - } - - DataProjection mvDP = dataImportService.findDataProjectionByLabel("MarkerVariant"); - - if(mvDP == null){ - - mvDP = new DataProjection(); - mvDP.setLabel("MarkerVariant"); - } - - DataProjection drugDP = dataImportService.findDataProjectionByLabel("ModelDrugData"); - - if(drugDP == null){ - - drugDP = new DataProjection(); - drugDP.setLabel("ModelDrugData"); - } - - DataProjection ihcDP = dataImportService.findDataProjectionByLabel("breast cancer markers"); - - if(ihcDP == null){ - ihcDP = new DataProjection(); - ihcDP.setLabel("breast cancer markers"); - } - - DataProjection cytoDP = dataImportService.findDataProjectionByLabel("cytogenetics"); - - if(cytoDP == null){ - cytoDP = new DataProjection(); - cytoDP.setLabel("cytogenetics"); - } - - DataProjection cnaDP = dataImportService.findDataProjectionByLabel("copy number alteration"); - - - if(cnaDP == null){ - cnaDP = new DataProjection(); - cnaDP.setLabel("copy number alteration"); - } - - - DataProjection expDP = dataImportService.findDataProjectionByLabel("expression"); - - - if(expDP == null){ - expDP = new DataProjection(); - expDP.setLabel("expression"); - } - - - DataProjection daDP = dataImportService.findDataProjectionByLabel("data available"); - - if(daDP == null){ - daDP = new DataProjection(); - daDP.setLabel("data available"); - } - - DataProjection fmgDP = dataImportService.findDataProjectionByLabel("frequently mutated genes"); - - if(fmgDP == null){ - fmgDP = new DataProjection(); - fmgDP.setLabel("frequently mutated genes"); - } - - DataProjection ptDP = dataImportService.findDataProjectionByLabel("patient treatment"); - - if(ptDP == null){ - ptDP = new DataProjection(); - ptDP.setLabel("patient treatment"); - } - - DataProjection ddDP = dataImportService.findDataProjectionByLabel("drug dosing counter"); - - if(ddDP == null){ - ddDP = new DataProjection(); - ddDP.setLabel("drug dosing counter"); - } + saveDP("PlatformMarkerVariantModel", mutatedPlatformMarkerVariantModelDP); + saveDP("MarkerVariant", mutatedMarkerVariantDP); + saveDP("ModelDrugData", modelDrugResponseDP); + saveDP("breast cancer markers", immunoHistoChemistryDP); + saveDP("cytogenetics", cytogeneticsDP); + saveDP("copy number alteration", copyNumberAlterationDP); + saveDP("expression", expressionDP); + saveDP("data available", dataAvailableDP); + saveDP("frequently mutated genes", frequentlyMutatedMarkersDP); + saveDP("patient treatment", patientTreatmentDP); + saveDP("drug dosing counter", drugDosingDP); - JSONObject json; + } + public DataProjection saveDP(String dpName, Object values){ - try{ - json = new JSONObject(mutatedPlatformMarkerVariantModelDP.toString()); - pmvmDP.setValue(json.toString()); - } - catch(Exception e){ + DataProjection dataProjection = dataImportService.findDataProjectionByLabel(dpName); - e.printStackTrace(); - log.error(mutatedPlatformMarkerVariantModelDP.toString()); + if(dataProjection== null){ + dataProjection = new DataProjection(); + dataProjection.setLabel(dpName); } - try{ - json = new JSONObject(mutatedMarkerVariantDP.toString()); - mvDP.setValue(json.toString()); - } - catch(Exception e){ - e.printStackTrace(); - log.error(mutatedMarkerVariantDP.toString()); - } - try{ - json = new JSONObject(modelDrugResponseDP.toString()); - drugDP.setValue(json.toString()); - } - catch(Exception e){ - e.printStackTrace(); - log.error(modelDrugResponseDP.toString()); - } + dataProjection.setValue(createJsonString(values)); + return dataImportService.saveDataProjection(dataProjection); + } - try{ - json = new JSONObject(immunoHistoChemistryDP.toString()); - ihcDP.setValue(json.toString()); + public String createJsonString(Object jstring){ + try { + return JSONObject.wrap(jstring).toString(); } catch(Exception e){ - e.printStackTrace(); - log.error(immunoHistoChemistryDP.toString()); + log.error("There was an error serializing the map object to JSON"); } + return ""; + } - try{ - json = new JSONObject(copyNumberAlterationDP.toString()); - cnaDP.setValue(json.toString()); - } - catch(Exception e){ - e.printStackTrace(); - log.error(copyNumberAlterationDP.toString()); - } - try{ - json = new JSONObject(dataAvailableDP.toString()); - daDP.setValue(json.toString()); - } - catch(Exception e){ + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + context = applicationContext; + } - e.printStackTrace(); - log.error(dataAvailableDP.toString()); - } - - try{ - json = new JSONObject(patientTreatmentDP.toString()); - ptDP.setValue(json.toString()); - System.out.println(); - } - catch(Exception e){ - e.printStackTrace(); - log.error(patientTreatmentDP.toString()); - } + public void setMutatedPlatformMarkerVariantModelDP(Map<String, Map<String, Map<String, Set<Long>>>> mutatedPlatformMarkerVariantModelDP) { + this.mutatedPlatformMarkerVariantModelDP = mutatedPlatformMarkerVariantModelDP; + } - try{ - fmgDP.setValue(frequentlyMutatedMarkersDP.toString()); - } - catch(Exception e){ + public void setMutatedMarkerVariantDP(Map<String, Set<String>> mutatedMarkerVariantDP) { + this.mutatedMarkerVariantDP = mutatedMarkerVariantDP; + } - e.printStackTrace(); - log.error(frequentlyMutatedMarkersDP.toString()); - } + public void setModelForQueryDP(List<ModelForQuery> modelForQueryDP) { + this.modelForQueryDP = modelForQueryDP; + } - try{ - json = new JSONObject(cytogeneticsDP.toString()); - cytoDP.setValue(json.toString()); + public void setModelDrugResponseDP(Map<String, Map<String, Set<Long>>> modelDrugResponseDP) { + this.modelDrugResponseDP = modelDrugResponseDP; + } - } - catch(Exception e){ - e.printStackTrace(); - log.error(cytogeneticsDP.toString()); - } + public void setImmunoHistoChemistryDP(Map<String, Map<String, Set<Long>>> immunoHistoChemistryDP) { + this.immunoHistoChemistryDP = immunoHistoChemistryDP; + } - try{ - json = new JSONObject(expressionDP.toString()); - expDP.setValue(json.toString()); + public void setCytogeneticsDP(Map<String, Map<String, Set<Long>>> cytogeneticsDP) { + this.cytogeneticsDP = cytogeneticsDP; + } - } - catch(Exception e){ - e.printStackTrace(); - log.error(expressionDP.toString()); - } + public void setCopyNumberAlterationDP(Map<String, Set<Long>> copyNumberAlterationDP) { + this.copyNumberAlterationDP = copyNumberAlterationDP; + } - try{ - json = new JSONObject(drugDosingDP.toString()); - ddDP.setValue(json.toString()); + public void setExpressionDP(Map<String, Map<String, Set<Long>>> expressionDP) { + this.expressionDP = expressionDP; + } - } - catch(Exception e){ - e.printStackTrace(); - log.error(drugDosingDP.toString()); - } + public void setDataAvailableDP(Map<String, List<DataAvailableDTO>> dataAvailableDP) { + this.dataAvailableDP = dataAvailableDP; + } + public void setFrequentlyMutatedMarkersDP(List<MutatedMarkerData> frequentlyMutatedMarkersDP) { + this.frequentlyMutatedMarkersDP = frequentlyMutatedMarkersDP; + } - dataImportService.saveDataProjection(pmvmDP); - dataImportService.saveDataProjection(mvDP); - dataImportService.saveDataProjection(drugDP); - dataImportService.saveDataProjection(ihcDP); - dataImportService.saveDataProjection(cnaDP); - dataImportService.saveDataProjection(daDP); - dataImportService.saveDataProjection(fmgDP); - dataImportService.saveDataProjection(ptDP); - dataImportService.saveDataProjection(cytoDP); - dataImportService.saveDataProjection(expDP); - dataImportService.saveDataProjection(ddDP); + public void setDrugDosingDP(Map<String, Set<Long>> drugDosingDP) { + this.drugDosingDP = drugDosingDP; + } + public void setPatientTreatmentDP(Map<String, Set<Long>> patientTreatmentDP) { + this.patientTreatmentDP = patientTreatmentDP; } + public Map<String, Map<String, Map<String, Set<Long>>>> getMutatedPlatformMarkerVariantModelDP() { + return mutatedPlatformMarkerVariantModelDP; + } + public Map<String, Set<String>> getMutatedMarkerVariantDP() { + return mutatedMarkerVariantDP; + } - private String createJsonString(Object jstring){ + public List<ModelForQuery> getModelForQueryDP() { + return modelForQueryDP; + } - try{ + public Map<String, Map<String, Set<Long>>> getModelDrugResponseDP() { + return modelDrugResponseDP; + } - JSONObject json = new JSONObject(jstring); - return json.toString(); - } - catch(Exception e){ + public Map<String, Map<String, Set<Long>>> getImmunoHistoChemistryDP() { + return immunoHistoChemistryDP; + } - e.printStackTrace(); - } + public Map<String, Map<String, Set<Long>>> getCytogeneticsDP() { + return cytogeneticsDP; + } - return ""; + public Map<String, Set<Long>> getCopyNumberAlterationDP() { + return copyNumberAlterationDP; } - private void dumpDataToFile(){ - log.info("Dumping data to file"); - String fileName = "/Users/csaba/Documents/pdxFinderDump.txt"; - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, false)); + public Map<String, Map<String, Set<Long>>> getExpressionDP() { + return expressionDP; + } - writer.append(immunoHistoChemistryDP.toString()); - writer.close(); + public Map<String, List<DataAvailableDTO>> getDataAvailableDP() { + return dataAvailableDP; + } - } catch (IOException e) { - e.printStackTrace(); - } + public List<MutatedMarkerData> getFrequentlyMutatedMarkersDP() { + return frequentlyMutatedMarkersDP; + } + public Map<String, Set<Long>> getDrugDosingDP() { + return drugDosingDP; } - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - context = applicationContext; + public Map<String, Set<Long>> getPatientTreatmentDP() { + return patientTreatmentDP; } } diff --git a/indexer/src/main/java/org/pdxfinder/postload/MolcharAPITest.java b/indexer/src/main/java/org/pdxfinder/postload/MolcharAPITest.java index 9542e2d5f12540b156853d80f8d8fd936b6910cf..81f17764e2852e93e5095ca9a8678fe3208070b4 100644 --- a/indexer/src/main/java/org/pdxfinder/postload/MolcharAPITest.java +++ b/indexer/src/main/java/org/pdxfinder/postload/MolcharAPITest.java @@ -67,7 +67,7 @@ public class MolcharAPITest implements CommandLineRunner{ long startTime = System.currentTimeMillis(); - MolecularDataTableDTO dto = detailsService.getMolecularDataTable(id.toString()); + MolecularDataTableDTO dto = detailsService.getMolecularDataTable(id.toString(), false); long endTime = System.currentTimeMillis(); long totalTime = endTime - startTime; diff --git a/indexer/src/main/java/org/pdxfinder/postload/SetDataVisibility.java b/indexer/src/main/java/org/pdxfinder/postload/SetDataVisibility.java index 671ef458752923cbc899eae2f8abb2051a1e03a6..5fd19c7dfc5b3a8dc7d7529be0374347a6b87629 100644 --- a/indexer/src/main/java/org/pdxfinder/postload/SetDataVisibility.java +++ b/indexer/src/main/java/org/pdxfinder/postload/SetDataVisibility.java @@ -30,6 +30,8 @@ public class SetDataVisibility { log.info("Applying data visibility rules"); applyDataVisibilityRules("CRL"); + applyDataVisibilityRules("Curie-LC"); + applyDataVisibilityRules("Curie-BC"); long endTime = System.currentTimeMillis(); long totalTime = endTime - startTime; @@ -42,26 +44,24 @@ public class SetDataVisibility { } - private void applyDataVisibilityRules(String datasourceAbbrev){ + public void applyDataVisibilityRules(String datasourceAbbrev){ log.info("Disabling data visibility for "+datasourceAbbrev); int molcharCounter = dataImportService.findMolcharNumberByDataSource(datasourceAbbrev); for(int i=0; i < molcharCounter; i+=50){ - List<MolecularCharacterization> molChars = dataImportService.findMolcharByDataSourceSkipLimit(datasourceAbbrev, i, 50); - - for(MolecularCharacterization mc:molChars){ - - mc.setVisible(false); - dataImportService.saveMolecularCharacterization(mc); - } - + disableVisibility(molChars); + dataImportService.saveMolecularCharacterizations(molChars); } + } + public void disableVisibility(List<MolecularCharacterization> molChars){ + for(MolecularCharacterization mc:molChars){ + mc.setVisible(false); + } } - } diff --git a/indexer/src/main/java/org/pdxfinder/postload/ValidateDB.java b/indexer/src/main/java/org/pdxfinder/postload/ValidateDB.java deleted file mode 100644 index 0c315d3a7824a82a11a752d0b5ae281a6206dafd..0000000000000000000000000000000000000000 --- a/indexer/src/main/java/org/pdxfinder/postload/ValidateDB.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.pdxfinder.postload; - -/* - * Created by csaba on 15/11/2018. - */ - -import joptsimple.OptionParser; -import joptsimple.OptionSet; -import org.pdxfinder.graph.dao.DataProjection; -import org.pdxfinder.graph.dao.Marker; -import org.pdxfinder.graph.dao.OntologyTerm; -import org.pdxfinder.services.DataImportService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.CommandLineRunner; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.stereotype.Service; - -import java.util.HashSet; -import java.util.Set; - -@Service -@Order(value = 92) -public class ValidateDB { - - private static Logger log = LoggerFactory.getLogger(ValidateDB.class); - - private DataImportService dataImportService; - - - public ValidateDB(DataImportService dataImportService) { - this.dataImportService = dataImportService; - } - - public void run() { - - log.info("******************************************************"); - log.info("* Starting validation checks *"); - log.info("******************************************************"); - - runValidationChecks(); - - } - - - private void runValidationChecks(){ - - - /* - Scenarios when DB is invalid: - - Missing DataProjection nodes - - Patients with multiple treatmentsummaries - - Scenarios when DB is valid with warnings: - - Found nodes without relationships and they are not DataProjections - - Platforms without url attribute value - */ - - - - - boolean isDBValid = true; - boolean noWarnings = true; - - //check if there is any unlinked nodes that are not dataprojections - - - log.info("Looking for sad nodes (nodes without a relationship)"); - Set<String> unlinkedNodeTypeSet = new HashSet<>(); - /* - //this is disabled now, needs to be batched - - Set<Object> unlinkedNodes = dataImportService.findUnlinkedNodes(); - - if(unlinkedNodes.size() == 0){ - log.error("DataProjection nodes not found - invalid database!"); - isDBValid = false; - } - else{ - - for(Object node : unlinkedNodes){ - - if(!(node instanceof DataProjection || node instanceof Marker || node instanceof OntologyTerm) ){ - //Uh-oh! We found a lonely node that is not DataProjection or Marker!!! - unlinkedNodeTypeSet.add(node.getClass().getSimpleName()); - } - } - } - - */ - - - //check if there is any patient with multiple treatment summaries - log.info("Looking for patients with multiple treatment summaries"); - Set<Object> patientsWithMultipleSummaries = dataImportService.findPatientsWithMultipleSummaries(); - - if(patientsWithMultipleSummaries.size() > 0){ - isDBValid = false; - - log.error("Found patients with multiple treatment summaries!"); - } - - //check if there is any platform without url - log.info("Validating platforms"); - Set<Object> platformsWithoutUrl = dataImportService.findPlatformsWithoutUrl(); - - if(platformsWithoutUrl.size() > 0){ - - noWarnings = false; - log.warn("Found Platforms without url: "+ platformsWithoutUrl.toString()); - } - - - - //TODO: Check if DataProjection nodes are there - //TODO: Define additional db checks! - - - - //list errors - if(unlinkedNodeTypeSet.size() > 0){ - noWarnings = false; - log.warn("Node types found without a relationship: "+unlinkedNodeTypeSet.toString()); - log.warn("Get those nodes a relationship!"); - } - - - //inform user - if(noWarnings && isDBValid){ - - log.info("*******************************************************"); - log.info("* Finished DB validation: VALID DATABASE, NO WARNINGS *"); - log.info("*******************************************************"); - } - else if(!noWarnings){ - log.warn("********************************************************"); - log.warn("* Finished DB validation: VALID DATABASE WITH WARNINGS *"); - log.warn("********************************************************"); - } - else if(!isDBValid){ - - log.error("*******************************************************"); - log.error("* Finished DB validation: INVALID DATABASE *"); - log.error("*******************************************************"); - } - - - - } - -} diff --git a/indexer/src/main/java/org/pdxfinder/reportmanager/ReportManager.java b/indexer/src/main/java/org/pdxfinder/reportmanager/ReportManager.java index d0ac01d3b736b2a5b99905d7b5ff72f90f398af2..4d6d9bf1953a786643b8caf6b0f546aa4569c201 100644 --- a/indexer/src/main/java/org/pdxfinder/reportmanager/ReportManager.java +++ b/indexer/src/main/java/org/pdxfinder/reportmanager/ReportManager.java @@ -6,6 +6,8 @@ package org.pdxfinder.reportmanager; import org.pdxfinder.services.reporting.LogEntity; import org.pdxfinder.services.reporting.MarkerLogEntity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -16,6 +18,8 @@ import java.util.List; @Order(value = -80) public class ReportManager { + private final static Logger log = LoggerFactory.getLogger(ReportManager.class); + private List<LogEntity> messages; public ReportManager() { @@ -32,18 +36,14 @@ public class ReportManager { public void printMessages(String level){ - if(messages.size() == 0){ - System.out.println("There are no message entries in the Report Manager."); + if (messages.size() == 0) { + log.info("There are no message entries in the Report Manager."); } - else{ - + else { for(LogEntity le: messages){ - if(le.getType().equals(level) || level.equals("ALL")){ - System.out.println(le); + log.info(le.toString()); } - - } } } diff --git a/indexer/src/main/java/org/pdxfinder/utils/CbpTransformer.java b/indexer/src/main/java/org/pdxfinder/utils/CbpTransformer.java index 6d05049b538eb4405248c014ff5b7db995960873..cae7d0c2ab94af2089203c7257395eb3743fb269 100644 --- a/indexer/src/main/java/org/pdxfinder/utils/CbpTransformer.java +++ b/indexer/src/main/java/org/pdxfinder/utils/CbpTransformer.java @@ -1,7 +1,10 @@ package org.pdxfinder.utils; -import org.pdxfinder.dataexport.UniversalDataExporter; +import org.apache.poi.ss.usermodel.Sheet; +import org.pdxfinder.TSV; +import org.pdxfinder.dataexport.ExporterTemplates; +import org.pdxfinder.dataexport.UniversalDataWriterServices; import org.pdxfinder.graph.dao.Group; import org.pdxfinder.services.OmicTransformationService; import org.pdxfinder.services.UtilityService; @@ -13,10 +16,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @Service @@ -26,56 +26,62 @@ public class CbpTransformer { private UtilityService utilityService; private OmicTransformationService omicTransformationService; - private UniversalDataExporter universalDataExporter; + private UniversalDataWriterServices universalDataWriterUtilities; - CbpTransformer(UtilityService utilityService, OmicTransformationService omicTransformationService, UniversalDataExporter universalDataExporter){ + CbpTransformer(UtilityService utilityService, OmicTransformationService omicTransformationService, + UniversalDataWriterServices universalDataWriterUtilities){ this.utilityService = utilityService; this.omicTransformationService = omicTransformationService; - this.universalDataExporter = universalDataExporter; + this.universalDataWriterUtilities = universalDataWriterUtilities; } - private static String notSpecified = "Not Specified"; private static String patientId = "patientId"; private static String sampleId = "sampleId"; - private static String entrezGeneId = "EntrezGeneId"; - + private static String entrezGeneId = "entrezGeneId"; + private static String mutFileId = TSV.molecular_characterisation_type.mut.name(); + private static String cnaFileId = TSV.molecular_characterisation_type.cna.name(); public enum cbioType { MUT, GISTIC } public void exportCBP(File exportDir,File templateDir, File pathToJson, cbioType dataType) throws IOException { - if (doesFileNotExist(exportDir) || doesFileNotExist(templateDir) || doesFileNotExist(pathToJson)) { throw new IOException(String.format("A string argument passed to the exportCBP does not point to an existing file." + "%s %n %s %n %s %n", exportDir, templateDir, pathToJson)); } + ExporterTemplates templates = new ExporterTemplates(templateDir.toString(), false); Group jsonGroup = createGroupWithJsonsFilename(pathToJson.getAbsolutePath()); - List<Map<String, Object>> listMapTable = utilityService.serializeJSONToMaps(pathToJson.getAbsolutePath()); - cbpMapsToSheetsByDataType(listMapTable, dataType); - - universalDataExporter.setDs(jsonGroup); - universalDataExporter.setTemplateDir(templateDir.getAbsolutePath()); - universalDataExporter.export(exportDir.getAbsolutePath()); + List<List<String>> cbioParsedData = cbpMapsToSheetsByDataType(listMapTable, dataType); + + Path providerDir = Paths.get(exportDir + "/" + jsonGroup.getAbbreviation()); + String exportUri = ""; + if(dataType.equals(cbioType.MUT)) { + exportUri = String.format("%s/%s/%s_%s", providerDir,mutFileId,jsonGroup.getAbbreviation(),mutFileId); + Sheet mutationTemplate = templates.getTemplate(TSV.templateNames.mutation_template.name()).getSheetAt(0); + universalDataWriterUtilities.writeSingleOmicFileToTsv(exportUri,mutationTemplate, cbioParsedData); + } else if(dataType.equals(cbioType.GISTIC)){ + exportUri = String.format("%s/%s/%s_%s", providerDir,cnaFileId,jsonGroup.getAbbreviation(),cnaFileId); + Sheet cnaTemplate = templates.getTemplate(TSV.templateNames.cna_template.name()).getSheetAt(0); + universalDataWriterUtilities.writeSingleOmicFileToTsv(exportUri,cnaTemplate, cbioParsedData); + } } - private void cbpMapsToSheetsByDataType(List<Map<String, Object>> listMapTable, cbioType dataType){ - - List<List<String>> sheet; + private List<List<String>> cbpMapsToSheetsByDataType(List<Map<String, Object>> listMapTable, cbioType dataType){ + List<List<String>> parsedCbioData = new ArrayList<>(); if(dataType.equals(cbioType.MUT)){ - sheet = cbpMutJsonMapsToSheet(listMapTable); - universalDataExporter.setMutationSheetDataExport(sheet); + parsedCbioData = cbpMutJsonMapsToSheet(listMapTable); } - else if(dataType.equals(cbioType.GISTIC)) { - sheet = cbpGisticsonMapsToSheet(listMapTable); - universalDataExporter.setCnaSheetDataExport(sheet); + else if(dataType.equals(cbioType.GISTIC)) { + parsedCbioData = cbpGisticsonMapsToSheet(listMapTable); } + return parsedCbioData; } private List<List<String>> cbpMutJsonMapsToSheet(List<Map<String, Object>> jsonMap){ AtomicInteger rowCount = new AtomicInteger(); - List<List<String>> sheet = new ArrayList<>(); + List<List<String>> cbioData = new ArrayList<>(); jsonMap.forEach(f -> { try { rowCount.incrementAndGet(); @@ -85,28 +91,30 @@ public class CbpTransformer { row.add(notSpecified); row.add(notSpecified); row.add(notSpecified); - row.add(omicTransformationService.ncbiGeneIdToHgncSymbol(String.valueOf(f.get(entrezGeneId)))); - addBlanksToList(row, 9); + row.add(parseHugoGeneDetails((LinkedHashMap<Object, Object>) f.get("gene"))); + addBlanksToList(row, 7); + row.add(String.valueOf(f.getOrDefault("tumorAltCount", ""))); + row.add(""); row.add(f.get("chr").toString()); row.add(f.get("startPosition").toString()); row.add(f.get("referenceAllele").toString()); row.add(f.get("variantAllele").toString()); addBlanksToList(row, 6); row.add(f.get("ncbiBuild").toString()); - row.add(""); - sheet.add(row); + cbioData.add(row); }catch(NullPointerException e){ log.error(String.format("Missing value in Json Mut map. Skipping Json Map %d", rowCount.get())); } }); - return sheet; + return cbioData; } private List<List<String>> cbpGisticsonMapsToSheet(List<Map<String,Object>> jsonMap){ + List<List<String>> cbioData = new ArrayList<>(); - List<List<String>> sheet = new ArrayList<>(); jsonMap.forEach(f -> { + try { List<String> row = new LinkedList<>(); row.add(f.get(patientId).toString()); row.add(f.get(sampleId).toString()); @@ -114,15 +122,27 @@ public class CbpTransformer { row.add(notSpecified); row.add(notSpecified); addBlanksToList(row,3); - row.add(omicTransformationService.ncbiGeneIdToHgncSymbol(String.valueOf(f.get(entrezGeneId)))); - row.add(f.get(entrezGeneId).toString()); - addBlanksToList(row, 6); + row.add(parseHugoGeneDetails((LinkedHashMap<Object, Object>) f.get("gene"))); + row.add(""); + row.add(f.getOrDefault(entrezGeneId, "").toString()); + addBlanksToList(row, 5); row.add(f.get("alteration").toString()); addBlanksToList(row, 3); - - sheet.add(row); + cbioData.add(row); + }catch(NullPointerException e){ + log.error("Missing value in Json gistic map. Skipping Json Map row"); + } }); - return sheet; + return cbioData; + } + + private String parseHugoGeneDetails(LinkedHashMap<Object, Object> geneDetails){ + String hugoGene = (String) geneDetails.getOrDefault("hugoGeneSymbol", ""); + if (hugoGene.isEmpty()) { + hugoGene = omicTransformationService + .ncbiGeneIdToHgncSymbol((String) geneDetails.getOrDefault(entrezGeneId,"")); + } + return hugoGene; } private Group createGroupWithJsonsFilename(String pathToJson) { diff --git a/indexer/src/main/java/org/pdxfinder/utils/CreateLocalFeeds.java b/indexer/src/main/java/org/pdxfinder/utils/CreateLocalFeeds.java index bf800d821709611909b36297bd5e5913c17b0108..f71e7d7640405e97dba2ed683497b9755478f84e 100644 --- a/indexer/src/main/java/org/pdxfinder/utils/CreateLocalFeeds.java +++ b/indexer/src/main/java/org/pdxfinder/utils/CreateLocalFeeds.java @@ -1,11 +1,8 @@ package org.pdxfinder.utils; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import joptsimple.OptionParser; import joptsimple.OptionSet; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; +import com.github.openjson.*; import org.pdxfinder.services.TransformerService; import org.pdxfinder.services.UtilityService; import org.slf4j.Logger; @@ -13,14 +10,12 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.PropertySource; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.io.*; -import java.nio.charset.Charset; -import java.util.ArrayList; import java.util.List; -import java.util.Map; /** @@ -44,6 +39,7 @@ import java.util.Map; * Created by csaba on 08/10/2018. */ @Component +@PropertySource("classpath:datafeed.properties") @Order(value = 0) public class CreateLocalFeeds implements CommandLineRunner { diff --git a/indexer/src/main/resources/application.properties b/indexer/src/main/resources/application.properties index 370a66a47a869dfef50e51b3741288505af2de81..a080aa66c838c2c5a9f0dfcc18dfa7fe515212bb 100644 --- a/indexer/src/main/resources/application.properties +++ b/indexer/src/main/resources/application.properties @@ -1,108 +1,30 @@ -cd # Disable spring web components from loading -spring.main.web-environment=false - -# Default logging level to INFO -logging.level.=INFO - -# Tone down Spring extra-chatty components -logging.level.org.springframework.boot.autoconfigure.logging=ERROR -logging.level.org.springframework.data.neo4j.mapping.Neo4jPersistentProperty=ERROR -logging.level.org.neo4j.ogm.drivers.http.request.HttpRequest=ERROR -logging.level.org.neo4j.ogm.drivers.embedded.request.EmbeddedRequest=ERROR -#spring.data.neo4j.username=neo4j -#spring.data.neo4j.password=neo5j -spring.data.neo4j.embedded.enabled=true -spring.data.neo4j.uri=file://${user.home}/Documents/pdx.graphdb - +# Logging +logging.path=log/ +logging.group.graphdb=org.neo4j, org.springframework.data.neo4j +logging.level.root=info +logging.level.graphdb=error +logging.pattern.console=%d{HH:mm:ss::SSS} %highlight(%-5level) %clr(%-40.40C){cyan} : %m%n%wEx + +# Local data location defaults +data-dir= +pdxfinder.root.dir= db-cache-dir=${user.home}/Documents/cache db-refresh=false - -# NON-GRAPH Datasource Config properties -spring.datasource.url=jdbc:h2:${data-dir}/h2-db/data;AUTO_SERVER=true;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=neo4j -spring.datasource.password=neo5j -spring.datasource.driver-class-name=org.h2.Driver -spring.h2.console.settings.trace=true -spring.jpa.hibernate.ddl-auto=update - - -jaxpdx.file= -jaxpdx.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?allModels=gimme -jaxpdx.variation.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelVariation= -jaxpdx.histology.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelHistology= -jaxpdx.cna.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelCNV= -jaxpdx.rnaseq.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelExpression= -# quit after loading this many variants for a model (one model has ~63000) -# -1 will load all, 0 will load none -jaxpdx.variation.max=-1 - -# This is unlikely to change for years, but we might want to look at patch numbers? -jaxpdx.ref.assembly=GRCh38 - - -pdmrpdx.file=pdxinfo.json -pdmrpdx.url= -pdmrpdx.variation.url= -pdmrpdx.histology.url= -pdmrpdx.variation.max=-1 -pdmrpdx.ref.assembly= -pdmrpdx.mutations.file - -#For MD Anderson -mdapdx.url= -mda.urls= - -#For Huntsman Cancer Institute -hcipdx.url= -hci.ihc.file= - - -#For WISTAR -wistarpdx.url= - -#WUSTL -wustl.urls= - - -#New IRCC -irccpdx.url= -irccpdx.variation.url= -irccpdx.variation.max =-1 - - ncitpredef.file= - - - -#mappings file containing diagnosis to NCIT links +data.directory= +provider= mappings.diagnosis.file=file.json - -#mappings file containing diagnosis to NCIT links mappings.diagnosis.file2=file.json - -#a list of template file uri separated with a comma -universal.template.files= - -# root directory for local data feeds -data-dir= -pdxfinder.root.dir= - -# local directory for log files -pdxfinder.log.dir=${data-dir} - mappings.mappedTermUrl=http://localhost/data/mappings.json -data.directory= +# Graph database config +spring.data.neo4j.uri=file://${user.home}/Documents/pdx.graphdb -provider= +# Relational database config +h2.datasource.jdbc-url=jdbc:h2:${data-dir}/h2-db/data;AUTO_SERVER=true;DB_CLOSE_ON_EXIT=FALSE +h2.datasource.username=neo4j +h2.datasource.password=neo5j +h2.datasource.driver-class-name=org.h2.Driver +spring.h2.console.settings.trace=true +spring.jpa.hibernate.ddl-auto=update -# Email Notification Configurations -#spring.mail.default-encoding = UTF-8 -#spring.mail.host = mail.pdxinder.org -#spring.mail.username = -#spring.mail.password = -#spring.mail.port: 26 -#spring.mail.properties.mail.smtp.auth = true -#spring.mail.properties.mail.smtp.auth.starttls.enable = true -#spring.mail.protocol = smtp -#spring.mail.test-connection = false \ No newline at end of file diff --git a/indexer/src/main/resources/datafeed.properties b/indexer/src/main/resources/datafeed.properties new file mode 100644 index 0000000000000000000000000000000000000000..b36adaefc84464014db8680fad2355b854850b76 --- /dev/null +++ b/indexer/src/main/resources/datafeed.properties @@ -0,0 +1,33 @@ +# Local feed constants + +jaxpdx.ref.assembly=GRCh38 +jaxpdx.file= +jaxpdx.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?allModels=gimme +jaxpdx.variation.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelVariation= +jaxpdx.histology.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelHistology= +jaxpdx.cna.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelCNV= +jaxpdx.rnaseq.url=http://tumor.informatics.jax.org/PDXInfo/JSONData.do?modelExpression= +# -1 will load all, 0 will load none +jaxpdx.variation.max=-1 + +pdmrpdx.file=pdxinfo.json +pdmrpdx.url= +pdmrpdx.variation.url= +pdmrpdx.histology.url= +pdmrpdx.variation.max=-1 +pdmrpdx.ref.assembly= +pdmrpdx.mutations.file + +mdapdx.url= +mda.urls= + +hcipdx.url= +hci.ihc.file= + +wistarpdx.url= + +wustl.urls= + +irccpdx.url= +irccpdx.variation.url= +irccpdx.variation.max =-1 \ No newline at end of file diff --git a/indexer/src/main/resources/loader.properties b/indexer/src/main/resources/loader.properties index 5aa6ddc0066615a2a82e96190550f30b50fd1f2c..a5705949b452945407af232b916b017b6e88a896 100644 --- a/indexer/src/main/resources/loader.properties +++ b/indexer/src/main/resources/loader.properties @@ -15,7 +15,7 @@ hci.projectGroup = PDXNet hci.nsgBsName = NOD scid gamma hci.nsgBsSymbol = NOD.Cg-Prkdc<sup>scid</sup> Il2rg<sup>tm1Wjl</sup>/SzJ -hci.nsgBsDesc +hci.nsgBsDesc = hci.nsgbsURL = http://jax.org/strain/005557 hci.nsBsName = NOD scid @@ -117,7 +117,7 @@ ircc.projectGroup = EurOPDX ircc.nsgBsName = NOD scid gamma ircc.nsgBsSymbol = NOD.Cg-Prkdc<sup>scid</sup> Il2rg<sup>tm1Wjl</sup>/SzJ -ircc.nsgBsDesc +ircc.nsgBsDesc = ircc.nsgbsURL = http://jax.org/strain/005557 ircc.nsBsName = ircc.nsBsSymbol = diff --git a/indexer/src/main/resources/logback.xml b/indexer/src/main/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..92a6d2c5916efc5d7bdf10306157388d2920ad66 --- /dev/null +++ b/indexer/src/main/resources/logback.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration scan="true"> + + <!--include configuration from spring boot's application properties--> + <include resource="org/springframework/boot/logging/logback/base.xml"/> + <!--suppress logback config logging--> + <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> + + <appender name="Validator" class="ch.qos.logback.core.FileAppender"> + <file>log/validation_errors.html</file> + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="ch.qos.logback.classic.html.HTMLLayout"> + <pattern>%level%msg</pattern> + <cssBuilder class="ch.qos.logback.classic.html.UrlCssBuilder"> + <url>../web/src/main/resources/static/css/validationLog.css</url> + </cssBuilder> + </layout> + </encoder> + </appender> + + <appender name="RollingLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>log/debug.log</file> + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> + <Pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n</Pattern> + </encoder> + <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> + <fileNamePattern>log/archived/log_%d{dd-MM-yyyy}.log</fileNamePattern> + <totalSizeCap>100MB</totalSizeCap> + </rollingPolicy> + </appender> + + <root level="debug"> + <appender-ref ref="RollingLog" /> + </root> + + <logger name="org.pdxfinder.dataloaders.updog.tablevalidation.Validator" level="ERROR"> + <appender-ref ref="Validator" /> + </logger> + + +</configuration> diff --git a/indexer/src/test/java/org/pdxfinder/BaseTest.java b/indexer/src/test/java/org/pdxfinder/BaseTest.java index 3934a36986a655a36f424a6178f53cda2ab2f44b..684a08a842f6afe0fa80bdd87574754f36492378 100644 --- a/indexer/src/test/java/org/pdxfinder/BaseTest.java +++ b/indexer/src/test/java/org/pdxfinder/BaseTest.java @@ -15,7 +15,7 @@ import org.springframework.transaction.annotation.Transactional; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) @ContextConfiguration(classes = {TestConfig.class}) -@TestPropertySource(locations = {"classpath:ogm.properties"}) +@TestPropertySource(locations = {"classpath:application.properties"}) @Transactional @Ignore public class BaseTest { diff --git a/indexer/src/test/java/org/pdxfinder/TestConfig.java b/indexer/src/test/java/org/pdxfinder/TestConfig.java index fa46ff413bcef433dcebe5372f381376e33b123c..15b78f7bc8004ee83df9020fa887d855547872b7 100755 --- a/indexer/src/test/java/org/pdxfinder/TestConfig.java +++ b/indexer/src/test/java/org/pdxfinder/TestConfig.java @@ -9,12 +9,23 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; @Configuration @EnableTransactionManagement -@EnableNeo4jRepositories("org.pdxfinder.graph.repositories") +@EnableNeo4jRepositories(value = "org.pdxfinder.graph.repositories") public class TestConfig { +/* + @Bean + public SessionFactory sessionFactory() { + return new SessionFactory("org.pdxfinder"); + } + +*/ + @Bean + public org.neo4j.ogm.config.Configuration getConfiguration() { + return new org.neo4j.ogm.config.Configuration.Builder().build(); + } @Bean public SessionFactory sessionFactory() { - return new SessionFactory("org.pdxfinder.*"); + return new SessionFactory(getConfiguration(), "org.pdxfinder.*"); } @Bean @@ -23,3 +34,4 @@ public class TestConfig { } } + diff --git a/indexer/src/test/java/org/pdxfinder/commandline/FinderCommandLineTest.java b/indexer/src/test/java/org/pdxfinder/commandline/FinderCommandLineTest.java index e09e256dbb7335b0559d440e06227bb9e6c79f5d..a56fb8bbd3908a3436ccf13c2cb1da6d300e0355 100644 --- a/indexer/src/test/java/org/pdxfinder/commandline/FinderCommandLineTest.java +++ b/indexer/src/test/java/org/pdxfinder/commandline/FinderCommandLineTest.java @@ -25,57 +25,38 @@ public class FinderCommandLineTest extends BaseTest { @Mock private FinderTransformer finderTransformer; @InjectMocks private FinderCommandLine.Transform transform; - @Mock private FinderExporter finderExporter; - @InjectMocks private FinderCommandLine.Export export; - @Before public void setUp() { MockitoAnnotations.initMocks(this); doNothing().when(this.finderLoader).run( - anyListOf(DataProvider.class), - any(File.class), - anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() + anyListOf(DataProvider.class), + any(File.class), + anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() ); } - /* @Test public void givenLoadOnlyMinimal_LoaderIsCalled() { - String[] args = {"--only=Test_Minimal", "--data-dir=path/", "--keep-db"}; + String[] args = {"--only=Test_Minimal", "--data-dir=path/"}; int exitCode = new CommandLine(load).execute(args); assertEquals(0, exitCode); verify(this.finderLoader).run( - anyListOf(DataProvider.class), - any(File.class), - anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() + anyList(), + any(File.class), + anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() ); verifyNoMoreInteractions(this.finderLoader); } @Test public void givenLoadAll_callsLoader() { - String[] args = {"--group=All", "--data-dir=path/", "--keep-db"}; + String[] args = {"--group=All", "--data-dir=path/"}; int exitCode = new CommandLine(load).execute(args); assertEquals(0, exitCode); verify(this.finderLoader).run( - anyListOf(DataProvider.class), - any(File.class), - anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() - ); - verifyNoMoreInteractions(this.finderLoader); - } -*/ - @Test public void givenTransform_When_exportAllisCalled_Then_callsTransformer() throws IOException { - String[] args = {"--data-dir=path/", "-c=MUT"}; - int exitCode = new CommandLine(transform).execute(args); - assertEquals(0, exitCode); - verify(this.finderTransformer).run( + anyList(), any(File.class), - any(), - any(), - any(File.class), - any(), - any() + anyBoolean(), anyBoolean(), anyBoolean(), anyBoolean() ); - verifyNoMoreInteractions(this.finderTransformer); + verifyNoMoreInteractions(this.finderLoader); } @Test public void givenTransform_When_cbioPortalIsCalled_Then_callsTransformer() throws IOException { @@ -93,7 +74,6 @@ public class FinderCommandLineTest extends BaseTest { verifyNoMoreInteractions(this.finderTransformer); } - @Test public void givenTransform_WhenTwoExclusiveArgumentsArepassed_Then_ReturnNonZeroExit() { String[] args = {"--data-dir=path/", "--export=test", "--all"}; int exitCode = new CommandLine(transform).execute(args); diff --git a/indexer/src/test/java/org/pdxfinder/commandline/FinderExporterTest.java b/indexer/src/test/java/org/pdxfinder/commandline/FinderExporterTest.java index 2cf9d73944dd4f82704af9fda4e04910a3f9281e..75fd924f4f4f0a31d17c6dfc19f00b767dbb97b8 100644 --- a/indexer/src/test/java/org/pdxfinder/commandline/FinderExporterTest.java +++ b/indexer/src/test/java/org/pdxfinder/commandline/FinderExporterTest.java @@ -4,11 +4,12 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; import org.pdxfinder.BaseTest; +import org.pdxfinder.dataexport.UniversalDataExtractionServices; import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.boot.test.mock.mockito.SpyBean; import java.io.File; import java.io.IOException; @@ -23,33 +24,47 @@ public class FinderExporterTest extends BaseTest { public TemporaryFolder folder = new TemporaryFolder(); private File tempFile; - @MockBean - private UtilityService utilityService; - @MockBean + @Mock private DataImportService dataImportService; + @Mock + private UniversalDataExtractionServices universalDataExtractionUtilities; - @SpyBean - FinderExporter finderExporter; + @Spy + @InjectMocks + private FinderExporter finderExporter; @Before public void init() throws IOException { tempFile = folder.newFile(); } @Test - public void Given_loadAllisTrue_When_runIsCalled_Then_CallExportAll() throws IOException { + public void given_loadAllisTrue_When_runIsCalled_Then_CallExportAll() throws IOException { finderExporter.setDefaultDirectory(tempFile.getAbsolutePath()); - finderExporter.run(null, null, true); - verify(finderExporter).exportAllGroups(any(File.class)) ; + finderExporter.run(null, null, true,false ); + verify(finderExporter).exportAllGroups(any(File.class), eq(false)) ; } @Test - public void Given_provider_when_runIsCalled_Then_CallExport() throws IOException { + public void given_provider_when_runIsCalled_Then_CallExport() throws IOException { finderExporter.setDefaultDirectory(tempFile.getAbsolutePath()); - finderExporter.run(null, "test", false); + finderExporter.run(null, "test", false,false); verify(finderExporter).export( eq(tempFile.getAbsoluteFile()), - eq("test") + eq("test"), + eq(false) ); } + @Test + public void given_WithSingleProviderAndharmonizedIsTrue_when_runisCalled_Then_CallExport() throws IOException { + finderExporter.setDefaultDirectory(tempFile.getAbsolutePath()); + finderExporter.run(null, "test", false, true); + verify(finderExporter).export( + eq(tempFile.getAbsoluteFile()), + eq("test"), + eq(true) + ); + + } + } diff --git a/indexer/src/test/java/org/pdxfinder/commandline/FinderLoaderTest.java b/indexer/src/test/java/org/pdxfinder/commandline/FinderLoaderTest.java index b08241f560643e7e297182db82bdc6483f228410..397e46cc6fe175c91d0cd6227a55c5cc8c5fa1b2 100644 --- a/indexer/src/test/java/org/pdxfinder/commandline/FinderLoaderTest.java +++ b/indexer/src/test/java/org/pdxfinder/commandline/FinderLoaderTest.java @@ -10,27 +10,24 @@ import org.pdxfinder.BaseTest; import org.pdxfinder.LoadDiseaseOntology; import org.pdxfinder.dataloaders.LoadJAXData; import org.pdxfinder.dataloaders.updog.Updog; -import org.pdxfinder.services.constants.DataProvider; -import org.pdxfinder.dataloaders.LoadAdditionalDatasets; import org.pdxfinder.mapping.LinkSamplesToNCITTerms; import org.pdxfinder.mapping.LinkTreatmentsToNCITTerms; import org.pdxfinder.postload.CreateDataProjections; import org.pdxfinder.postload.SetDataVisibility; -import org.pdxfinder.postload.ValidateDB; import org.pdxfinder.services.DataImportService; +import org.pdxfinder.services.constants.DataProvider; import org.pdxfinder.services.constants.DataUrl; import org.pdxfinder.services.loader.envload.LoadMarkers; import org.pdxfinder.services.loader.envload.LoadNCIT; import org.pdxfinder.services.loader.envload.LoadNCITDrugs; -import java.nio.file.Path; import java.io.File; +import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; -import static org.mockito.Mockito.verifyNoMoreInteractions; public class FinderLoaderTest extends BaseTest { @@ -46,12 +43,10 @@ public class FinderLoaderTest extends BaseTest { private DataProvider updogDataProvider; private static boolean NO_VALIDATION_ONLY = false; - @Mock private LoadAdditionalDatasets loadAdditionalDatasets; @Mock private LinkSamplesToNCITTerms linkSamplesToNCITTerms; @Mock private LinkTreatmentsToNCITTerms linkTreatmentsToNCITTerms; @Mock private CreateDataProjections createDataProjections; @Mock private SetDataVisibility setDataVisibility; - @Mock private ValidateDB validateDB; @Mock private File dataDirectory; @Spy @@ -68,12 +63,10 @@ public class FinderLoaderTest extends BaseTest { doNothing().when(this.loadMarkers).loadGenes(anyString()); doNothing().when(this.loadNCIT).loadOntology(anyString()); doNothing().when(this.loadNCITDrugs).loadRegimens(); - doNothing().when(this.loadAdditionalDatasets).run(); doNothing().when(this.linkSamplesToNCITTerms).run(); doNothing().when(this.linkTreatmentsToNCITTerms).run(); doNothing().when(this.createDataProjections).run(); doNothing().when(this.setDataVisibility).run(); - doNothing().when(this.validateDB).run(); doNothing().when(this.updog).run(any(Path.class), anyString(), anyBoolean()); this.dataProvider = DataProvider.JAX; diff --git a/indexer/src/test/java/org/pdxfinder/commandline/FinderTransformerTest.java b/indexer/src/test/java/org/pdxfinder/commandline/FinderTransformerTest.java index 269cd22820e4fb4a9bdc119bea5a8891ed1c7803..6da7986fd0dc8dc4c498686a6346d8340867aa8b 100644 --- a/indexer/src/test/java/org/pdxfinder/commandline/FinderTransformerTest.java +++ b/indexer/src/test/java/org/pdxfinder/commandline/FinderTransformerTest.java @@ -1,9 +1,6 @@ package org.pdxfinder.commandline; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import org.junit.rules.TemporaryFolder; import org.mockito.*; import org.pdxfinder.BaseTest; @@ -14,7 +11,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import java.io.File; import java.io.IOException; -import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; public class FinderTransformerTest extends BaseTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/CbpTransformerTests.java b/indexer/src/test/java/org/pdxfinder/dataexport/CbpTransformerTests.java index 6be033b079209d67b44c602936368a3dd469716d..6710fbd2dcf29870806e3992cf19419ea21af9af 100644 --- a/indexer/src/test/java/org/pdxfinder/dataexport/CbpTransformerTests.java +++ b/indexer/src/test/java/org/pdxfinder/dataexport/CbpTransformerTests.java @@ -1,27 +1,33 @@ package org.pdxfinder.dataexport; -import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.*; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; import org.pdxfinder.BaseTest; +import org.pdxfinder.TSV; import org.pdxfinder.services.OmicTransformationService; import org.pdxfinder.services.UtilityService; import org.pdxfinder.utils.CbpTransformer; import org.pdxfinder.utils.CbpTransformer.cbioType; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Paths; +import java.util.*; -import java.io.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class CbpTransformerTests extends BaseTest { @@ -34,16 +40,18 @@ public class CbpTransformerTests extends BaseTest { @Mock private OmicTransformationService omicTransformationService; @Mock - private UniversalDataExporter universalDataExporter; + private UniversalDataWriterServices universalDataWriterUtilities; + @Captor + private ArgumentCaptor<ArrayList<List<String>>> captor; @InjectMocks private CbpTransformer cbpTransformer; private File jsonDummy; private File exportFolder; - private File templatesFolder; private cbioType mutDataType; private cbioType gisticDataType; + private String templatesFolder; @Before public void init() throws IOException { @@ -54,30 +62,33 @@ public class CbpTransformerTests extends BaseTest { TemporaryFolder rootFolder = new TemporaryFolder(); rootFolder.create(); exportFolder = rootFolder.newFolder(); - templatesFolder = rootFolder.newFolder(); - createMockTemplate(); + + TemporaryFolder templateRoot = new TemporaryFolder(); + templateRoot.create(); + templatesFolder = templateRoot.getRoot().getAbsolutePath(); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.metadata_template.fileName, 7); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.sampleplatform_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.mutation_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.cna_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.cytogenetics_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.expression_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.drugdosing_template.fileName, 2); + writeWorkbook(templatesFolder + "/" + TSV.templateNames.patienttreatment_template.fileName, 2); } - public void createMockTemplate() throws IOException { + private void writeWorkbook(String directory, int sheetCount) throws IOException { + OutputStream out = new FileOutputStream(directory); XSSFWorkbook workbook = new XSSFWorkbook(); - Sheet omic = workbook.createSheet("Test"); - Row headers = omic.createRow(0); - for(int i = 0; i < 25; i++){ - headers.createCell(i).setCellValue(i ); + for (int i = 0; i < sheetCount; i++) { + workbook.createSheet(); } - - FileOutputStream out = new FileOutputStream(new File(templatesFolder.getAbsoluteFile() + "/mutation_template.xlsx")); workbook.write(out); - out.close(); - - FileOutputStream cnaOut = new FileOutputStream(new File(templatesFolder.getAbsoluteFile() + "/cna_template.xlsx")); - workbook.write(cnaOut); - out.close(); } + @Test(expected = IOException.class) public void Given_nonExistentJsonFilesArePassed_WhenExportCBPisCalled_Then_throwIOexception() throws IOException { - cbpTransformer.exportCBP(exportFolder, templatesFolder, new File("/tmp/not/existing"), mutDataType); + cbpTransformer.exportCBP(exportFolder, new File(templatesFolder), new File("/tmp/not/existing"), mutDataType); } @Test(expected = IOException.class) @@ -87,9 +98,11 @@ public class CbpTransformerTests extends BaseTest { @Test public void Give_JsonArrayAndValidImportDirectory_When_exportsIsCalled__ThenNewMutDirExists() throws IOException { + String mut = TSV.molecular_characterisation_type.mut.mcType; + String mutFileId = TSV.molecular_characterisation_type.mut.name(); String ns = "Not Specified"; - List<Map<String, Object>> dummyListMap = new ArrayList<Map<String,Object >>(); + List<Map<String, Object>> dummyListMap = new ArrayList<>(); Map<String, Object> dummyMap= new HashMap<>(); dummyMap.put("patientId","1"); dummyMap.put("sampleId","2"); @@ -104,10 +117,47 @@ public class CbpTransformerTests extends BaseTest { when(utilityService.serializeJSONToMaps(jsonDummy.getAbsolutePath())) .thenReturn(dummyListMap); + cbpTransformer.exportCBP(exportFolder, new File(templatesFolder), jsonDummy, mutDataType); + + String filename = Paths.get(jsonDummy.getAbsolutePath()).getFileName().toString(); + String expectedExportURI = String.format("%s/%s/%s/%s_%s",exportFolder, filename,"mut",filename, mutFileId); + verify(universalDataWriterUtilities).writeSingleOmicFileToTsv(eq(expectedExportURI), any(Sheet.class), anyList()); + } + + @Test + public void Give_nestedGeneInformationInJason_When_cbioportalExporterIsCalled_ThenFileContainsGeneInformation() throws IOException { + String cnaFileId = TSV.molecular_characterisation_type.cna.name(); + String geneSymbol = "CELSR1"; + + Map<String, Object> geneMap = new LinkedHashMap<>(); + geneMap.put("entrezGeneId",9620); + geneMap.put("hugoGeneSymbol", geneSymbol); + geneMap.put("type", "protien_coding"); + + List<Map<String, Object>> dummyListMap = new ArrayList<>(); + Map<String, Object> dummyMap= new HashMap<>(); + dummyMap.put("patientId","1"); + dummyMap.put("sampleId","2"); + dummyMap.put("entrezGeneId","00001"); + dummyMap.put("chr","3"); + dummyMap.put("gene", geneMap); + dummyMap.put("startPosition","4"); + dummyMap.put("referenceAllele","5"); + dummyMap.put("alteration","2"); + dummyMap.put("ncbiBuild","7"); + dummyListMap.add(dummyMap); + + when(utilityService.serializeJSONToMaps(jsonDummy.getAbsolutePath())) + .thenReturn(dummyListMap); + + cbpTransformer.exportCBP(exportFolder, new File(templatesFolder), jsonDummy, gisticDataType); - cbpTransformer.exportCBP(exportFolder, templatesFolder, jsonDummy, mutDataType); + String filename = Paths.get(jsonDummy.getAbsolutePath()).getFileName().toString(); + String expectedExportURI = String.format("%s/%s/%s/%s_%s",exportFolder, filename,"cna",filename, cnaFileId); + verify(universalDataWriterUtilities).writeSingleOmicFileToTsv(eq(expectedExportURI), any(Sheet.class), captor.capture()); - Mockito.verify(universalDataExporter, times(1)).export(exportFolder.getAbsolutePath()); + String geneName = captor.getValue().get(0).get(8); + Assert.assertEquals(geneName, geneSymbol); } } diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/DataExportTest.java b/indexer/src/test/java/org/pdxfinder/dataexport/DataExportTest.java deleted file mode 100644 index a9d11baa4426ae637703a9e343e8aa003e228f86..0000000000000000000000000000000000000000 --- a/indexer/src/test/java/org/pdxfinder/dataexport/DataExportTest.java +++ /dev/null @@ -1,368 +0,0 @@ -package org.pdxfinder.dataexport; - -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.pdxfinder.BaseTest; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.services.DataImportService;; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.mockito.Mockito.when; - -public class DataExportTest extends BaseTest { - - @Mock - private DataImportService dataImportService; - - @InjectMocks - protected UniversalDataExporter universalDataExporter; - - Group providerGroup; - - private static final String ncbiId = "XR_929159.2"; - private static final String biotype = "protien_coding"; - private static final String codingSequenceChange = "3154G>A"; - private static final String variantClass = "SNV"; - - @Before - public void setUp() { - providerGroup = Group.createProviderGroup("TestGroup", "TG", "", "Academia", "Bob", "Bob's page"); - } - - @Test - public void Given_PatientAndProvider_When_GetPatientSheetIsCalled_Then_PatientDataIsInRowOne() { - - when(dataImportService.findPatientsByGroup(providerGroup)) - .thenReturn(getPatientListForTest()); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initPatientData(); - List<List<String>> patientData = universalDataExporter.getPatientSheetDataExport(); - - Assert.assertEquals("p123", patientData.get(0).get(0)); - } - - @Test - public void Given_PatientAndModelAndSample_When_PatientTumorSheetIsCalled_Then_PatientDataIsInRowOne(){ - - Patient patient = new Patient("p123", "male", "", "", providerGroup); - PatientSnapshot patientSnapshot = new PatientSnapshot(); - patientSnapshot.setAgeAtCollection("65"); - Sample sample = new Sample(); - sample.setSourceSampleId("s123"); - - TumorType tt = new TumorType("Metastatic"); - Tissue ot = new Tissue("Brain"); - Tissue ss = new Tissue("Brain"); - - sample.setType(tt); - sample.setOriginTissue(ot); - sample.setSampleSite(ss); - - patientSnapshot.addSample(sample); - patient.addSnapshot(patientSnapshot); - - List<Patient> patientList = new ArrayList<>(); - patientList.add(patient); - - ModelCreation modelCreation = new ModelCreation(); - modelCreation.setSourcePdxId("m123"); - - when(dataImportService.findPatientTumorAtCollectionDataByDS(providerGroup)) - .thenReturn(patientList); - when(dataImportService.findModelBySample(sample)) - .thenReturn(modelCreation); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initPatientTumorAtCollection(); - - List<List<String>> patientTumorAtCollection = universalDataExporter.getPatientTumorSheetDataExport(); - Assert.assertEquals("p123", patientTumorAtCollection.get(0).get(0)); - } - - @Test - public void Given_ModelWithDetails_When_GetModelDetailsIsCalled_Then_ModelDataIsInRowOne(){ - - when( dataImportService.findModelsWithSpecimensAndQAByDS(providerGroup.getAbbreviation())) - .thenReturn(getModelListForTest()); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initPdxModelDetails(); - universalDataExporter.initPdxModelValidations(); - - List<List<String>> pdxModelDetails = universalDataExporter.getPdxModelSheetDataExport(); - List<List<String>> pdxModelValidations = universalDataExporter.getPdxModelValidationSheetDataExport(); - - Assert.assertEquals("m123", pdxModelDetails.get(0).get(0)); - Assert.assertEquals("hsname", pdxModelDetails.get(0).get(1)); - - Assert.assertEquals("m123", pdxModelValidations.get(0).get(0)); - Assert.assertEquals("technology", pdxModelValidations.get(0).get(1)); - - } - - @Test - public void Given_Provider_When_GetSharingAndContactSheetIsCalled_Then_SharingAndContactDataIsInRowOne(){ - - when(dataImportService.findModelsWithSharingAndContactByDS(providerGroup.getAbbreviation())) - .thenReturn(getModelListForTest()); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initSharingAndContact(); - - List<List<String>> sharingAndContact = universalDataExporter.getSharingAndContactSheetDataExport(); - - Assert.assertEquals("m123", sharingAndContact.get(0).get(0)); - Assert.assertEquals("Academia", sharingAndContact.get(0).get(1)); - - } - - @Test - public void Given_Provider_When_GetLoaderRelatedSheetIsCalled_Then_DataIsInRowOne(){ - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initLoaderRelatedData(); - - List<List<String>> loaderRelatedData = universalDataExporter.getLoaderRelatedDataSheetDataExport(); - - Assert.assertEquals("TG", loaderRelatedData.get(0).get(1)); - - - } - - @Test - public void Given_ModelWithMolecularData_When_GetSamplePlatformSheetIsCalled_Then_SamplePlatformDataIsInRowOne(){ - - when(dataImportService.findModelXenograftPlatformSampleByDS(providerGroup.getAbbreviation())) - .thenReturn(getModelListForTest()); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initSamplePlatformDescription(); - - List<List<String>> samplePlatformDescription = universalDataExporter.getSamplePlatformDescriptionSheetDataExport(); - - Assert.assertEquals("s123", samplePlatformDescription.get(0).get(1)); - Assert.assertEquals("xs123", samplePlatformDescription.get(1).get(1)); - - } - - @Test - public void Given_ModelwithMutationData_When_initGenomicDataIsCalled_Then_MutationDataIsInRowOne(){ - - List<ModelCreation> modelList = getModelListForTest(); - - when(dataImportService.findModelsWithSharingAndContactByDS((providerGroup.getAbbreviation()))) - .thenReturn(modelList); - - when(dataImportService.findModelWithMolecularDataByDSAndIdAndMolcharType( - providerGroup.getAbbreviation(),"m123", "mutation")) - .thenReturn(modelList.get(0)); - - universalDataExporter.setDs(providerGroup); - universalDataExporter.initOmicData(); - List<List<String>> mutationData = universalDataExporter.getMutationSheetDataExport(); - - Assert.assertTrue(mutationData.get(0).contains(ncbiId)); - Assert.assertTrue(mutationData.get(0).contains(biotype)); - Assert.assertTrue(mutationData.get(0).contains(codingSequenceChange)); - Assert.assertTrue(mutationData.get(0).contains(variantClass)); - - } - - - @Test - public void Given_SheetRowData_When_UpdateSheetIsCalled_Then_SheetIsUpdated(){ - - Workbook wb = new XSSFWorkbook(); - Sheet sheet1 = wb.createSheet("Sheet1"); - - List<String> rowData = new ArrayList<>(Arrays.asList("1","2","3","4")); - List<List<String>> data = new ArrayList<>(); - data.add(rowData); - - universalDataExporter.updateSheetWithData(sheet1, data, 1, 1); - - Assert.assertEquals("2", sheet1.getRow(0).getCell(1).getStringCellValue()); - } - - @Test - public void Given_dataIsReadyToExport_When_exportIsCalled_Then_createCorrectFileStructure() throws IOException { - - Path metaData = Paths.get( "/tmp/metadata_template.xlsx"); - Path samplePlatform = Paths.get("/tmp/sampleplatform_template.xlsx" ); - Path mutation = Paths.get("/tmp/mutation_template.xlsx"); - Path cnaTemplate = Paths.get("/tmp/cna_template.xlsx"); - - List<List<String>> genericSheet = new ArrayList<>(); - List<String> genericColumn = new ArrayList<>(); - genericSheet.add(genericColumn); - - universalDataExporter.setPatientSheetDataExport(genericSheet); - universalDataExporter.setPatientTumorSheetDataExport(genericSheet); - universalDataExporter.setPatientTreatmentSheetDataExport(genericSheet); - universalDataExporter.setPdxModelSheetDataExport(genericSheet); - universalDataExporter.setPdxModelValidationSheetDataExport(genericSheet); - universalDataExporter.setSamplePlatformDescriptionSheetDataExport(genericSheet); - universalDataExporter.setSharingAndContactSheetDataExport(genericSheet); - universalDataExporter.setCytogeneticsSheetDataExport(genericSheet); - universalDataExporter.setLoaderRelatedDataSheetDataExport(genericSheet); - universalDataExporter.setDrugDosingSheetDataExport(genericSheet); - universalDataExporter.setCnaSheetDataExport(genericSheet); - universalDataExporter.setMutationSheetDataExport(genericSheet); - - - Workbook metaDataXlsx = new XSSFWorkbook(); - Workbook samplePlatformXlsx = new XSSFWorkbook(); - Workbook mutationXlsx = new XSSFWorkbook(); - Workbook cnaTemplateXlsx = new XSSFWorkbook(); - - for(int i = 0; i < 7; i++) { - metaDataXlsx.createSheet(String.format("%s", i)); - } - - samplePlatformXlsx.createSheet("0"); - mutationXlsx.createSheet("0"); - cnaTemplateXlsx.createSheet("0"); - - metaDataXlsx.write(new FileOutputStream(metaData.toFile())); - samplePlatformXlsx.write(new FileOutputStream(samplePlatform.toFile())); - mutationXlsx.write(new FileOutputStream(mutation.toFile())); - cnaTemplateXlsx.write(new FileOutputStream(cnaTemplate.toFile())); - - try { - universalDataExporter.setTemplateDir("/tmp"); - universalDataExporter.setDs(providerGroup); - universalDataExporter.initPatientData(); - universalDataExporter.export("/tmp"); - } finally { - - Files.delete(metaData); - Files.delete(samplePlatform); - Files.delete(mutation); - Files.delete(cnaTemplate); - } - - Path expectedProviderDir = Paths.get("/tmp/TG"); - Path expectedCnaDir = Paths.get("/tmp/TG/cna"); - Path expectedMutDir = Paths.get("/tmp/TG/mut"); - Path expectedMetaData = Paths.get("/tmp/TG/metadata.xlsx"); - - Assert.assertTrue(expectedProviderDir.toFile().exists()); - Assert.assertTrue(expectedCnaDir.toFile().exists()); - Assert.assertTrue(expectedMutDir.toFile().exists()); - Assert.assertTrue(expectedMetaData.toFile().exists()); - - } - - - - - private List<ModelCreation> getModelListForTest(){ - - List<ModelCreation> modelCreationList = new ArrayList<>(); - - ModelCreation model = new ModelCreation(); - model.setSourcePdxId("m123"); - - Group accessGroup = Group.createAccessibilityGroup("Academia", "transnational"); - Group project = new Group("project1", "p1", "Project"); - - Group publicationGroup = new Group(); - publicationGroup.setType("Publication"); - publicationGroup.setPubMedId("12345"); - - model.addGroup(publicationGroup); - model.addGroup(providerGroup); - model.addGroup(accessGroup); - model.addGroup(project); - - ExternalUrl url = new ExternalUrl(ExternalUrl.Type.CONTACT,"email@address.com"); - List<ExternalUrl> urlList = new ArrayList<>(); - urlList.add(url); - model.setExternalUrls(urlList); - - QualityAssurance qualityAssurance = new QualityAssurance("technology", "description", "1,2"); - model.addQualityAssurance(qualityAssurance); - - Sample patientSample = new Sample(); - patientSample.setSourceSampleId("s123"); - - model.setSample(patientSample); - - MolecularCharacterization molecularCharacterization = new MolecularCharacterization(); - molecularCharacterization.setType("mutation"); - molecularCharacterization.setTechnology("techtest"); - - MarkerAssociation ma = new MarkerAssociation(); - ma.setMolecularDataString("[{\"biotype\": \"" + biotype + "\",\"codingSequenceChange\":\"" + codingSequenceChange + "\"," + - "\"variantClass\":\""+ variantClass + "\",\"codonChange\"" + - ":\"Gtt/Att\",\"aminoAcidChange\":\"E763*\",\"consequence\":\"\",\"functionalPrediction\":\"Nonsense_Mutation\"," + - "\"readDepth\":\"403\",\"alleleFrequency\":\"0.464\",\"chromosome\":\"5\",\"seqStartPosition\":\"112173578\"," + - "\"refAllele\":\"G\",\"altAllele\":\"T\",\"ucscGeneId\":\"\",\"ncbiGeneId\":\"" + ncbiId + "\",\"ncbiTranscriptId\":" + - "\"XR_929159.2\",\"existingVariations\":\"CM106354,COSM5010432\",\"genomeAssembly\":\"hg19\",\"nucleotideChange\"" + - ":\"\",\"marker\":\"APC\"}]"); - - molecularCharacterization.setMarkerAssociations(Collections.singletonList(ma)); - Platform platform = new Platform(); - platform.setName("platform"); - platform.setUrl("platformurl"); - - molecularCharacterization.setPlatform(platform); - patientSample.addMolecularCharacterization(molecularCharacterization); - - //setting up the xeno sample - Specimen specimen = new Specimen(); - specimen.setPassage("1"); - specimen.setHostStrain(new HostStrain("hssymbol", "hsname")); - - Sample xenoSample = new Sample(); - xenoSample.setSourceSampleId("xs123"); - specimen.setSample(xenoSample); - xenoSample.addMolecularCharacterization(molecularCharacterization); - model.addSpecimen(specimen); - - - modelCreationList.add(model); - - //setting up cna data - MolecularCharacterization molecularCharacterization2 = new MolecularCharacterization(); - molecularCharacterization2.setType("copy number alteration"); - molecularCharacterization2.setPlatform(platform); - MolecularData md2 = new MolecularData(); - md2.setCnaCopyNumberStatus("cnaStatus"); - xenoSample.addMolecularCharacterization(molecularCharacterization2); - - return modelCreationList; - } - - private List<Patient> getPatientListForTest(){ - - Patient patient = new Patient("p123", "male", "", "", providerGroup); - patient.setCancerRelevantHistory(""); - patient.setFirstDiagnosis(""); - patient.setAgeAtFirstDiagnosis("60"); - - List<Patient> patientList = new ArrayList<>(); - patientList.add(patient); - - - - return patientList; - } - - -} diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/ExportTemplatesTest.java b/indexer/src/test/java/org/pdxfinder/dataexport/ExportTemplatesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b87e057f56a0389a7a2484d0eea1281353d307df --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/dataexport/ExportTemplatesTest.java @@ -0,0 +1,74 @@ +package org.pdxfinder.dataexport; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Assert; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.pdxfinder.BaseTest; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.Group; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + + +public class ExportTemplatesTest extends BaseTest { + + private String templateDir; + private Group group; + + + private void writeWorkbook(String directory, int sheetCount) throws IOException { + OutputStream out = new FileOutputStream(directory); + XSSFWorkbook workbook = new XSSFWorkbook(); + for (int i = 0; i < sheetCount; i++) { + workbook.createSheet(); + } + workbook.write(out); + } + + @Test + public void Give_dataIsHarmonized_When_exportTemplatesAreInitialized_Then_adjustedTemplatesIsMade() throws IOException { + TemporaryFolder templateRoot = new TemporaryFolder(); + templateRoot.create(); + templateDir = templateRoot.getRoot().getAbsolutePath(); + + OutputStream out = new FileOutputStream(templateDir + "/" + TSV.templateNames.metadata_template.fileName); + XSSFWorkbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet(TSV.metadataSheetNames.sample.name()); + Row row = sheet.createRow(0); + + for (int i = 0; i < 24; i++){ + row.createCell(i).setCellValue(String.valueOf(i)); + } + + for (int i = 1; i < 7; i++) { + workbook.createSheet(); + } + workbook.write(out); + writeWorkbook(templateDir + "/" + TSV.templateNames.sampleplatform_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.mutation_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.cna_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.cytogenetics_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.expression_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.drugdosing_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.patienttreatment_template.fileName, 2); + group = new Group("test", "test", "test"); + + ExporterTemplates templates = new ExporterTemplates(templateDir, true); + XSSFWorkbook actualMetadataTemplate = templates.getTemplate(TSV.templateNames.metadata_template.name()); + Sheet actualSheet = actualMetadataTemplate.getSheet(TSV.metadataSheetNames.sample.name()); + Row actualRow = actualSheet.getRow(0); + + Assert.assertEquals(actualRow.getCell(8).getStringCellValue(), "PDX Finder Harmonized Diagnosis"); + for(int i = 10; i < 25; i++){ + Assert.assertEquals(String.valueOf(i-1), actualRow.getCell(i).getStringCellValue()); + } + } + + + +} diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExportTests.java b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExportTests.java new file mode 100644 index 0000000000000000000000000000000000000000..af00c41b0cd37aeb0543cd50bc28a67071e8729f --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExportTests.java @@ -0,0 +1,165 @@ +package org.pdxfinder.dataexport; + + +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.pdxfinder.BaseTest; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.Group; +import org.pdxfinder.graph.dao.ModelCreation; +import org.pdxfinder.services.DataImportService; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.*; + +public class UniversalDataExportTests extends BaseTest { + + @Mock + private UniversalDataWriterServices writerUtilities; + + @Mock + private UniversalDataExtractionServices extractionUtilities; + + @Mock + private DataImportService dataImportService; + + @InjectMocks + private UniversalDataExporter universalDataExporter; + + private String templateDir; + private Group group; + private ExporterTemplates templates; + private List<List<String>> testSheet; + + + @Before + public void init() throws IOException { + TemporaryFolder templateRoot = new TemporaryFolder(); + templateRoot.create(); + templateDir = templateRoot.getRoot().getAbsolutePath(); + writeWorkbook(templateDir + "/" + TSV.templateNames.metadata_template.fileName, 7); + writeWorkbook(templateDir + "/" + TSV.templateNames.sampleplatform_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.mutation_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.cna_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.cytogenetics_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.expression_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.drugdosing_template.fileName, 2); + writeWorkbook(templateDir + "/" + TSV.templateNames.patienttreatment_template.fileName, 2); + + templateDir = templateRoot.getRoot().getAbsolutePath(); + templates = new ExporterTemplates(templateDir, false); + group = new Group("test", "test", "test"); + + testSheet = new ArrayList<>(); + ArrayList<String> testRow = new ArrayList<>(); + testSheet.add(testRow); + } + + private void writeWorkbook(String directory, int sheetCount) throws IOException { + OutputStream out = new FileOutputStream(directory); + XSSFWorkbook workbook = new XSSFWorkbook(); + for (int i = 0; i < sheetCount; i++) { + workbook.createSheet(); + } + workbook.write(out); + } + + @Test + public void Given_dummyTemplatesAndNoData_ExportSamplePlatform_ExtractionUtilitesAreCalledWithoutWrite() throws IOException { + universalDataExporter.exportSamplePlatform(templates, group, templateDir); + + verify(extractionUtilities, times(1)).extractSamplePlatform(group); + verify(writerUtilities, times(1)).updateXlsxSheetWithData(any(Sheet.class), + any(List.class), anyInt(), anyInt()); + + verify(writerUtilities, never()).writXlsxFromWorkbook(any(XSSFWorkbook.class), anyString()); + } + + @Test + public void Given_dummyTemplatesWithData_ExportSamplePlatform_ExtractionUtilitesAreCalledWithWrite() throws IOException { + when(extractionUtilities.extractSamplePlatform(group)).thenReturn(testSheet); + + XSSFWorkbook samplePlatformTemplate = templates.getTemplate(TSV.templateNames.sampleplatform_template.name()); + universalDataExporter.exportSamplePlatform(templates, group, templateDir); + + verify(writerUtilities).updateXlsxSheetWithData(eq(samplePlatformTemplate.getSheetAt(0)), + any(ArrayList.class), anyInt(), anyInt()); + verify(writerUtilities).writXlsxFromWorkbook(eq(samplePlatformTemplate), anyString()); + } + + @Test + public void Given_dummyTemplatesAndNoData_ExportMetadata_ExtractionUtilitesAreCalledWithoutWriting() throws IOException { + MetadataSheets metadataSheets = new MetadataSheets(); + when(extractionUtilities.extractMetadata(group, metadataSheets, false)).thenReturn(metadataSheets); + + universalDataExporter.exportMetadata(metadataSheets, templates, group, false, templateDir); + verify(writerUtilities, times(7)).updateXlsxSheetWithData(any(Sheet.class), + any(List.class), anyInt(), anyInt()); + + verify(writerUtilities, never()).writXlsxFromWorkbook(any(XSSFWorkbook.class), anyString()); + } + + @Test + public void Given_NoModels_When_callToExtractAndSaveOmicsByBatch_Then_doNotRun() throws IOException { + String molecularType = "Mutation"; + Path testExportURI = Paths.get("/path/to/export"); + when(universalDataExporter.getModelsByMolecularTypeAndDataSource(molecularType, group)) + .thenReturn(new ArrayList<>()); + + universalDataExporter.extractAndSaveOmicByBatch(molecularType, + templates.getTemplate(TSV.templateNames.mutation_template.name()),testExportURI, group); + + verify(writerUtilities, never()).saveHeadersToTsv(any(Sheet.class),anyString()); + verify(extractionUtilities, never()).extractModelsOmicData(any(ModelCreation.class), anyString()); + } + + @Test + public void Given_aSingleModel_When_callToExtractAndSaveOmicsByBatch_Then_runOnce() throws IOException { + String molecularType = "Mutation"; + Path testExportURI = Paths.get("/path/to/export"); + ModelCreation testModel = new ModelCreation(); + when(universalDataExporter.getModelsByMolecularTypeAndDataSource(molecularType, group)) + .thenReturn(Collections.singletonList(testModel)); + + universalDataExporter.extractAndSaveOmicByBatch(molecularType, + templates.getTemplate(TSV.templateNames.mutation_template.name()),testExportURI, group); + + verify(writerUtilities).saveHeadersToTsv(any(Sheet.class),eq(testExportURI.toString())); + verify(extractionUtilities).extractModelsOmicData(eq(testModel), eq(molecularType)); + verify(writerUtilities).appendDataToOmicTsvFile(anyList(), eq(testExportURI.toString())); + } + + @Test + public void Given_elevenModel_When_callToExtractAndSaveOmicsByBatch_Then_runOnceInBatchThenAgain() throws IOException { + String molecularType = "Mutation"; + Path testExportURI = Paths.get("/path/to/export"); + ModelCreation[] testModelList = new ModelCreation[11]; + for(int i = 0; i < 11; i++){ + testModelList[i] = new ModelCreation(); + } + + when(universalDataExporter.getModelsByMolecularTypeAndDataSource(molecularType, group)) + .thenReturn(Arrays.asList(testModelList)); + + universalDataExporter.extractAndSaveOmicByBatch(molecularType, + templates.getTemplate(TSV.templateNames.mutation_template.name()),testExportURI, group); + + verify(writerUtilities).saveHeadersToTsv(any(Sheet.class),eq(testExportURI.toString())); + verify(extractionUtilities, times(11)).extractModelsOmicData(any(ModelCreation.class), eq(molecularType)); + verify(writerUtilities, times(2)).appendDataToOmicTsvFile(anyList(), eq(testExportURI.toString())); + } +} diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExtractorUtilitiesTest.java b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExtractorUtilitiesTest.java new file mode 100644 index 0000000000000000000000000000000000000000..30f9224621428e446b74067074590abd92189e1f --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataExtractorUtilitiesTest.java @@ -0,0 +1,329 @@ +package org.pdxfinder.dataexport; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.pdxfinder.BaseTest; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.*; +import org.pdxfinder.services.DataImportService; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.when; + +public class UniversalDataExtractorUtilitiesTest extends BaseTest { + + @Mock + private DataImportService dataImportService; + + @InjectMocks + protected UniversalDataExtractionServices extractor; + + Group providerGroup; + + private static final String ncbiId = "XR_929159.2"; + private static final String biotype = "protien_coding"; + private static final String codingSequenceChange = "3154G>A"; + private static final String variantClass = "SNV"; + private static final String cnaLog2RCNA = "-0.01234"; + private static final String marker = "SMAD3"; + private static final String patientSampleId = "s123"; + private static final String xenoSampleId = "xs123"; + private static final String mutMolType = TSV.molecular_characterisation_type.mut.mcType; + private static final String cnaMolType = TSV.molecular_characterisation_type.cna.mcType; + + private String TEST_DRUG = "TEST_DRUG"; + private String TEST_DOSE = "TEST_DOSE"; + private String TEST_RESPONSE = "TEST_RESPONSE"; + private String MODEL_ID = "m123"; + private String PATIENT_ID = "PATIETNID"; + + @Before + public void setUp() { + providerGroup = Group.createProviderGroup("TestGroup", "TG", "", "Academia", "Bob", "Bob's page"); + } + + @Test + public void Given_PatientAndProvider_When_GetPatientSheetIsCalled_Then_PatientDataIsInRowOne() { + when(dataImportService.findPatientsByGroup(providerGroup)) + .thenReturn(getPatientListForTest()); + + List<List<String>> patientData = extractor.extractPatientSheet(providerGroup); + Assert.assertEquals("p123", patientData.get(0).get(0)); + } + + @Test + public void Given_PatientAndModelAndSample_When_PatientSampleSheetIsCalled_Then_PatientDataIsInRowOne(){ + Patient patient = new Patient("p123", "male", "", "", providerGroup); + PatientSnapshot patientSnapshot = new PatientSnapshot(); + patientSnapshot.setAgeAtCollection("65"); + Sample sample = new Sample(); + sample.setSourceSampleId("s123"); + + TumorType tt = new TumorType("Metastatic"); + Tissue ot = new Tissue("Brain"); + Tissue ss = new Tissue("Brain"); + + sample.setType(tt); + sample.setOriginTissue(ot); + sample.setSampleSite(ss); + + patientSnapshot.addSample(sample); + patient.addSnapshot(patientSnapshot); + + List<Patient> patientList = new ArrayList<>(); + patientList.add(patient); + + ModelCreation modelCreation = new ModelCreation(); + modelCreation.setSourcePdxId(MODEL_ID); + + when(dataImportService.findPatientTumorAtCollectionDataByDS(providerGroup)) + .thenReturn(patientList); + when(dataImportService.findModelBySample(sample)) + .thenReturn(modelCreation); + + extractor.extractSampleSheet(providerGroup, false); + + List<List<String>> patientSampleSheet = extractor.extractSampleSheet(providerGroup, false); + Assert.assertEquals("p123", patientSampleSheet.get(0).get(0)); + } + + @Test + public void Given_ModelWithDetails_When_GetModelDetailsIsCalled_Then_ModelDataIsInRowOne(){ + + when( dataImportService.findModelsWithSpecimensAndQAByDS(providerGroup.getAbbreviation())) + .thenReturn(getModelListForTest()); + + extractor.extractModelDetails(providerGroup); + extractor.extractModelValidations(providerGroup); + + List<List<String>> pdxModelDetails = extractor.extractModelDetails(providerGroup); + List<List<String>> pdxModelValidations = extractor.extractModelValidations(providerGroup); + + Assert.assertEquals(MODEL_ID, pdxModelDetails.get(0).get(0)); + Assert.assertEquals("hsname", pdxModelDetails.get(0).get(1)); + + Assert.assertEquals(MODEL_ID, pdxModelValidations.get(0).get(0)); + Assert.assertEquals("technology", pdxModelValidations.get(0).get(1)); + + } + + @Test + public void Given_Provider_When_GetSharingAndContactSheetIsCalled_Then_SharingAndContactDataIsInRowOne(){ + when(dataImportService.findModelsWithSharingAndContactByDS(providerGroup.getAbbreviation())) + .thenReturn(getModelListForTest()); + + List<List<String>> sharingAndContact = extractor.extractSharingAndContact(providerGroup); + + Assert.assertEquals(MODEL_ID, sharingAndContact.get(0).get(0)); + Assert.assertEquals("Academia", sharingAndContact.get(0).get(1)); + } + + @Test + public void Given_Provider_When_GetLoaderRelatedSheetIsCalled_Then_DataIsInRowOne(){ + List<List<String>> loaderRelatedData = extractor.extractLoaderRelatedData(providerGroup); + Assert.assertEquals("TG", loaderRelatedData.get(0).get(1)); + } + + @Test + public void Given_ModelWithMolecularData_When_GetSamplePlatformSheetIsCalled_Then_SamplePlatformDataIsInRowOne(){ + + when(dataImportService.findModelXenograftPlatformSampleByDS(providerGroup.getAbbreviation())) + .thenReturn(getModelListForTest()); + + List<List<String>> samplePlatformDescription = extractor.extractSamplePlatform(providerGroup); + + Assert.assertEquals(patientSampleId, samplePlatformDescription.get(0).get(1)); + Assert.assertEquals(xenoSampleId, samplePlatformDescription.get(2).get(1)); + } + + @Test + public void Given_XenograftSamplewithMutationAndCna_When_extractGroupOmicDataIsCalled_Then_returnAppropriateDataForEach(){ + List<ModelCreation> modelList = getModelListForTest(); + ModelCreation testModel = modelList.get(0); + + List<List<String>> mutationData = extractor.extractModelsOmicData(modelList.get(0),mutMolType); + List<List<String>> cnaData = extractor.extractModelsOmicData(testModel,cnaMolType); + Assert.assertTrue(mutationData.get(0).contains(ncbiId)); + Assert.assertTrue(mutationData.get(0).contains(biotype)); + Assert.assertTrue(mutationData.get(0).contains(codingSequenceChange)); + Assert.assertTrue(mutationData.get(0).contains(variantClass)); + Assert.assertFalse(mutationData.get(0).contains(cnaLog2RCNA)); + Assert.assertFalse(mutationData.get(0).contains(marker)); + + Assert.assertTrue(cnaData.get(0).contains(cnaLog2RCNA)); + Assert.assertTrue(cnaData.get(0).contains(marker)); + Assert.assertFalse(cnaData.get(0).contains(biotype)); + Assert.assertFalse(cnaData.get(0).contains(variantClass)); + } + + @Test + public void Given_PatientSamplewithMutationAndCna_When_extractGroupOmicDataIsCalled_Then_returnAppropriateDataForEach(){ + List<ModelCreation> modelList = getModelListForTest(); + ModelCreation testModel = modelList.get(0); + List<List<String>> mutationData = extractor.extractModelsOmicData(testModel, mutMolType); + List<List<String>> cnaData = extractor.extractModelsOmicData(testModel, cnaMolType); + Assert.assertTrue(mutationData.get(0).contains(ncbiId)); + Assert.assertFalse(mutationData.get(0).contains(marker)); + Assert.assertTrue(cnaData.get(0).contains(marker)); + Assert.assertFalse(cnaData.get(0).contains(biotype)); + } + + + @Test + public void Given_ModelwithMutationData_When_extractModelDataIsCalledwithDifferentMolcType_Then_NoDataIsRetrieved(){ + List<ModelCreation> modelList = getModelListForTest(); + ModelCreation testModel = modelList.get(0); + List<List<String>> expressionData = extractor.extractModelsOmicData(testModel,"expression"); + Assert.assertEquals(0, expressionData.size()); + } + + @Test + public void Given_ModelwithDosingData_When_extractModelIsCalled_Then_DrugDosingIsRetrieved(){ + List<ModelCreation> modelList = getModelListForTest(); + ModelCreation testModel = modelList.get(0); + testModel.setTreatmentSummary(buildTreatmentSummaryTreeToModel()); + List<List<String>> dosingData = extractor.extractModelsOmicData(testModel,"drug"); + Assert.assertEquals(1, dosingData.size()); + Assert.assertEquals(MODEL_ID, dosingData.get(0).get(2)); + Assert.assertEquals(TEST_DRUG, dosingData.get(0).get(4)); + Assert.assertEquals(TEST_DOSE, dosingData.get(0).get(6)); + Assert.assertEquals(TEST_RESPONSE, dosingData.get(0).get(10)); + } + + @Test + public void Given_ModelwithPatientData_When_extractModelIsCalled_Then_PatientTreatmentIsRetrieved(){ + List<ModelCreation> modelList = getModelListForTest(); + ModelCreation testModel = modelList.get(0); + testModel.getSample().getPatientSnapshot().setTreatmentSummary(buildTreatmentSummaryTreeToModel()); + List<List<String>> dosingData = extractor.extractModelsOmicData(testModel,"patientTreatment"); + Assert.assertEquals(1, dosingData.size()); + Assert.assertEquals(PATIENT_ID, dosingData.get(0).get(0)); + Assert.assertEquals(TEST_DRUG, dosingData.get(0).get(1)); + Assert.assertEquals(TEST_DOSE, dosingData.get(0).get(2)); + Assert.assertEquals(TEST_RESPONSE, dosingData.get(0).get(7)); + } + + + + private List<ModelCreation> getModelListForTest(){ + List<ModelCreation> modelCreationList = new ArrayList<>(); + + ModelCreation model = new ModelCreation(); + model.setSourcePdxId(MODEL_ID); + + setModelGroups(model); + setExternalUrl(model); + + QualityAssurance qualityAssurance = new QualityAssurance("technology", "description", "1,2"); + model.addQualityAssurance(qualityAssurance); + + Patient patient = new Patient(PATIENT_ID, new Group()); + PatientSnapshot patientSnapshot = new PatientSnapshot(patient, "0"); + + Sample patientSample = new Sample(); + patientSample.setSourceSampleId(patientSampleId); + patientSample.setPatientSnapshot(patientSnapshot); + + model.setSample(patientSample); + + Specimen specimen = new Specimen(); + specimen.setPassage("1"); + specimen.setHostStrain(new HostStrain("hssymbol", "hsname")); + + Sample xenoSample = new Sample(); + xenoSample.setSourceSampleId(xenoSampleId); + specimen.setSample(xenoSample); + model.addSpecimen(specimen); + + String mutJson = "[{\"biotype\": \"" + biotype + "\",\"codingSequenceChange\":\"" + codingSequenceChange + "\"," + + "\"variantClass\":\""+ variantClass + "\",\"codonChange\"" + + ":\"Gtt/Att\",\"aminoAcidChange\":\"E763*\",\"consequence\":\"\",\"functionalPrediction\":\"Nonsense_Mutation\"," + + "\"readDepth\":\"403\",\"alleleFrequency\":\"0.464\",\"chromosome\":\"5\",\"seqStartPosition\":\"112173578\"," + + "\"refAllele\":\"G\",\"altAllele\":\"T\",\"ucscGeneId\":\"\",\"ncbiGeneId\":\"" + ncbiId + "\",\"ncbiTranscriptId\":" + + "\"XR_929159.2\",\"existingVariations\":\"CM106354,COSM5010432\",\"genomeAssembly\":\"hg19\",\"nucleotideChange\"" + + ":\"\",\"marker\":\"APC\"}]"; + + String cnaJson = "[{\"chromosome\":\"\",\"seqStartPosition\":\"\",\"genomeAssembly\":\"\"," + + "\"seqEndPosition\":\"\",\"cnaLog10RCNA\":\"\",\"cnaLog2RCNA\":\"" + cnaLog2RCNA + "\"," + + "\"cnaCopyNumberStatus\":\"Normal\",\"cnaGisticValue\":\"\"" + + ",\"cnaPicnicValue\":\"\",\"marker\":\"" + marker + "\"}]"; + + Platform platform = new Platform(); + platform.setName("platform"); + platform.setUrl("platformurl"); + + MolecularCharacterization mutMc = createMolecularDataStructure(mutMolType, mutJson, platform); + MolecularCharacterization cnaMc = createMolecularDataStructure(cnaMolType, cnaJson, platform); + xenoSample.addMolecularCharacterization(mutMc); + xenoSample.addMolecularCharacterization(cnaMc); + patientSample.addMolecularCharacterization(mutMc); + patientSample.addMolecularCharacterization(cnaMc); + + modelCreationList.add(model); + return modelCreationList; + } + + private void setModelGroups(ModelCreation model){ + Group accessGroup = Group.createAccessibilityGroup("Academia", "transnational"); + Group project = new Group("project1", "p1", "Project"); + + Group publicationGroup = new Group(); + publicationGroup.setType("Publication"); + publicationGroup.setPubMedId("12345"); + + model.addGroup(publicationGroup); + model.addGroup(providerGroup); + model.addGroup(accessGroup); + model.addGroup(project); + } + + private void setExternalUrl(ModelCreation model){ + ExternalUrl url = new ExternalUrl(ExternalUrl.Type.CONTACT,"email@address.com"); + List<ExternalUrl> urlList = new ArrayList<>(); + urlList.add(url); + model.setExternalUrls(urlList); + } + + private List<Patient> getPatientListForTest(){ + + Patient patient = new Patient("p123", "male", "", "", providerGroup); + patient.setCancerRelevantHistory(""); + patient.setFirstDiagnosis(""); + patient.setAgeAtFirstDiagnosis("60"); + + List<Patient> patientList = new ArrayList<>(); + patientList.add(patient); + + return patientList; + } + + private MolecularCharacterization createMolecularDataStructure(String molType, String markerAssociation, Platform platform){ + MolecularCharacterization molecularCharacterization = new MolecularCharacterization(); + molecularCharacterization.setType(molType); + molecularCharacterization.setTechnology("techtest"); + + MarkerAssociation ma = new MarkerAssociation(); + ma.setMolecularDataString(markerAssociation); + + molecularCharacterization.setMarkerAssociations(Collections.singletonList(ma)); + molecularCharacterization.setPlatform(platform); + return molecularCharacterization; + } + + private TreatmentSummary buildTreatmentSummaryTreeToModel(){ + Treatment treatment = new Treatment(TEST_DRUG); + TreatmentComponent treatmentComponent = new TreatmentComponent(TEST_DOSE, treatment); + TreatmentProtocol treatmentProtocol = new TreatmentProtocol(); + treatmentProtocol.setComponents(Collections.singletonList(treatmentComponent)); + treatmentProtocol.setResponse(new Response(TEST_RESPONSE, treatmentProtocol)); + TreatmentSummary treatmentSummary = new TreatmentSummary(); + treatmentSummary.setTreatmentProtocols(Collections.singletonList(treatmentProtocol)); + return treatmentSummary; + } +} \ No newline at end of file diff --git a/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataWriterUtilitiesTests.java b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataWriterUtilitiesTests.java new file mode 100644 index 0000000000000000000000000000000000000000..6e8158a47e35de8aac1cd25abc38c1c6bd0d9518 --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/dataexport/UniversalDataWriterUtilitiesTests.java @@ -0,0 +1,112 @@ +package org.pdxfinder.dataexport; + +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.junit.Assert; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.pdxfinder.BaseTest; +import org.pdxfinder.services.DataImportService; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class UniversalDataWriterUtilitiesTests extends BaseTest { + + @Mock + private DataImportService dataImportService; + + @InjectMocks + protected UniversalDataWriterServices universalDataWriterUtilities; + + + @Test + public void Given_SheetRowData_When_UpdateSheetIsCalled_Then_SheetIsUpdated(){ + Workbook wb = new XSSFWorkbook(); + Sheet sheet1 = wb.createSheet("Sheet1"); + + List<String> rowData = new ArrayList<>(Arrays.asList("1","2","3","4")); + List<List<String>> data = new ArrayList<>(); + data.add(rowData); + + universalDataWriterUtilities.updateXlsxSheetWithData(sheet1, data, 1, 1); + Assert.assertEquals("2", sheet1.getRow(0).getCell(1).getStringCellValue()); + } + + @Test + public void Given_nonExistingDirectoryStructureURI_CreateExportDirectiesIsCalled_createFullStructure() throws IOException { + TemporaryFolder rootFolder = new TemporaryFolder(); + rootFolder.create(); + String rootFolderURI = rootFolder.getRoot().getAbsolutePath(); + String testExportURI = String.format("%s/%s/%s/data_mut.tsv", rootFolderURI, "testProvider", "mut"); + universalDataWriterUtilities.createExportDirectories(testExportURI); + Assert.assertTrue(Paths.get(testExportURI).getParent().toFile().exists()); + + } + + @Test + public void Given_templatesAndexportLocation_WhenCopyHeaderIsCalled_WriteHeadersToTsvThenEOF() throws IOException { + TemporaryFolder rootFolder = new TemporaryFolder(); + rootFolder.create(); + String tsvURI = String.format("%s/test_mut.tsv", rootFolder.getRoot().getAbsoluteFile()); + XSSFWorkbook templateWB = new XSSFWorkbook(); + templateWB.createSheet(); + Sheet sheet = templateWB.getSheetAt(0); + sheet.createRow(0); + Row row = sheet.getRow(0); + for(int i=0; i < 23; i++) { + row.createCell(i).setCellValue(i); + } + universalDataWriterUtilities.saveHeadersToTsv(sheet, tsvURI); + File actualFile = Paths.get(tsvURI).toFile(); + Assert.assertTrue(actualFile.exists()); + BufferedReader reader = new BufferedReader(new FileReader(tsvURI)); + String[] delimitedHeaders = reader.readLine().split("\t"); + float index = 0; + for(String header: delimitedHeaders){ + Assert.assertEquals(String.format("%.1f", index), header); + index++; + } + Assert.assertEquals( null, reader.readLine()); + } + + @Test + public void Given_dataTableWithOneRow_WhenAppendedDataIsCalled_WriteToFirstLineThenToSecond() throws IOException{ + TemporaryFolder rootFolder = new TemporaryFolder(); + rootFolder.create(); + String tsvURI = String.format("%s/test_mut.tsv", rootFolder.getRoot().getAbsoluteFile()); + List<List<String>> testProviderData = new ArrayList<>(); + List<String> testRow = new ArrayList<>(); + for(int i = 0; i < 23; i++){ + testRow.add(String.valueOf(i)); + } + testProviderData.add(testRow); + universalDataWriterUtilities.appendDataToOmicTsvFile(testProviderData, tsvURI); + universalDataWriterUtilities.appendDataToOmicTsvFile(testProviderData, tsvURI); + BufferedReader reader = new BufferedReader(new FileReader(tsvURI)); + String[] actualDelimitedCellValues1 = reader.readLine().split("\t"); + String[] actualDelimitedCellValues2 = reader.readLine().split("\t"); + + testForSequentialCellValues(actualDelimitedCellValues1); + testForSequentialCellValues(actualDelimitedCellValues2); + Assert.assertEquals( null, reader.readLine()); + } + + private void testForSequentialCellValues(String[] delimitedCellValues){ + int index = 0; + for(String cellData: delimitedCellValues){ + Assert.assertEquals(String.valueOf(index), cellData); + index++; + } + } +} diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/LoadIRCCTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/LoadIRCCTest.java deleted file mode 100644 index 5395cbbff30f5258978d2488519915a01395edc4..0000000000000000000000000000000000000000 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/LoadIRCCTest.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.MockitoAnnotations; -import org.neo4j.ogm.json.JSONArray; -import org.neo4j.ogm.json.JSONObject; -import org.pdxfinder.BaseTest; -import org.pdxfinder.graph.dao.*; -import org.pdxfinder.graph.repositories.SpecimenRepository; -import org.pdxfinder.services.DataImportService; -import org.pdxfinder.services.UtilityService; -import org.springframework.boot.test.mock.mockito.MockBean; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.when; - -public class LoadIRCCTest extends BaseTest { - - private Group transnationalAccess; - private Group badAccess; - - - - @Before public void init() { - MockitoAnnotations.initMocks(this); - transnationalAccess = new Group(); - transnationalAccess.setName("transnational access"); - badAccess = new Group(); - badAccess.setName("another group"); - - loader.providerDS = Group.createProviderGroup( - "Test IRCC Provider", - "IRCC-CRC", - "Test provider description", - "Academia", - "Joe Bloggs", - "ircc.example.com"); - } - - @MockBean UtilityService utilityService; - @MockBean DataImportService dataImportService; - @MockBean SpecimenRepository specimenRepository; - @InjectMocks private LoadIRCC loader; - - @Test - public void Given_ValidSpecimen_WhenLoadSpecimen_Then_SpecimenAddedToModel() throws Exception { - ModelCreation modelCreation = new ModelCreation("1"); - JSONArray specimens = new JSONArray( - "[{" + - "\"Specimen ID\":\"CRCTEST\"," + - "\"Engraftment Type\":\"tissue fragment\"," + - "\"Engraftment Site\":\"subcutis right\"," + - "\"Strain\":\"NOD SCID\"," + - "\"Passage\":\"1\"," + - "\"Platforms\":[ " + - "{\"Platform\":\"RealTimePCR_GCN\"}" + - "]" + - "}]" - ); - JSONObject json = specimens.getJSONObject(0); - Specimen specimen = new Specimen(); - specimen.setExternalId(json.getString("Specimen ID")); - specimen.setPassage(json.getString("Passage")); - - loader.dto.setModelCreation(modelCreation); - loader.dto.setSpecimens(specimens); - - - when(dataImportService.getSpecimen( - modelCreation, - json.getString("Specimen ID"), - loader.providerDS.getAbbreviation(), - json.getString("Passage")) - ).thenReturn(specimen); - - loader.step13LoadSpecimens(); - - assertEquals( "CRCTEST", loader.dto.getSpecimens().getJSONObject(0).getString("Specimen ID")); - assertThat(loader.dto.getModelCreation().getSpecimens().contains(specimen), is(true)); - } - - @Test - public void Given_IRCCCRCModel_When_AddAccessModality_Then_AddToTransnationalAccessGroup() { - when(dataImportService.getAccessibilityGroup("", "transnational access")) - .thenReturn(transnationalAccess); - - ModelCreation mc = new ModelCreation(); - loader.dto.setModelCreation(mc); - loader.step18SetAdditionalGroups(); - - assertThat(loader.dto.getModelCreation().getGroups().contains(transnationalAccess), is(true)); - assertThat(loader.dto.getModelCreation().getGroups().contains(badAccess), is(false)); - } - -} diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/UniversalLoaderTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/UniversalLoaderTest.java deleted file mode 100644 index f72dbd8a153a5b2390918a62afe683f95eb96d25..0000000000000000000000000000000000000000 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/UniversalLoaderTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.pdxfinder.dataloaders; - -import org.apache.poi.ss.usermodel.Workbook; -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.MockitoAnnotations; -import org.pdxfinder.BaseTest; - -import java.util.Optional; - -import static org.junit.Assert.assertEquals; - -public class UniversalLoaderTest extends BaseTest { - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - @InjectMocks private UniversalLoader loader; - - @Test - public void Given_BaseFilePathContainsTrailingSlash_WhenLoading_PathIsCleaned() { - assertEquals("file/path", UniversalLoader.stripTrailingSlash("file/path/")); - } - - @Test - public void Given_BaseFilePathDoesNotContainTrailingSlash_WhenLoading_PathIsClean() { - assertEquals("file/path", UniversalLoader.stripTrailingSlash("file/path")); - } - - @Test - public void Given_NonExistingExcelTemplate_WhenLoading_ReturnOptionalEmpty() { - Optional<Workbook> workbook = loader.getWorkbook(".", "does/not/exist/test.xlsx"); - assertEquals(Optional.empty(), workbook); - } - -} diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/UpdogTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/UpdogTest.java index 701a6b0a245229007b341ffd0cd9ef59884ae26c..3a0d2a504a3cb4d30ac425193d0c926732f64ca8 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/UpdogTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/UpdogTest.java @@ -181,4 +181,4 @@ public class UpdogTest { ); } -} \ No newline at end of file +} diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreatorTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreatorTest.java index 695ab79a9a2669ee433722b1d9e01f576cb77646..95da74b0e25076781446726c0a5afb36b08683d1 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreatorTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/ModelCreationCreatorTest.java @@ -1,17 +1,12 @@ package org.pdxfinder.dataloaders.updog.domainobjectcreation; -import org.apache.catalina.Host; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.pdxfinder.dataloaders.updog.TSV; -import org.pdxfinder.graph.dao.Group; -import org.pdxfinder.graph.dao.HostStrain; -import org.pdxfinder.graph.dao.ModelCreation; -import org.pdxfinder.graph.dao.Sample; -import org.pdxfinder.graph.dao.Specimen; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.*; import tech.tablesaw.api.Row; import tech.tablesaw.api.Table; @@ -20,7 +15,7 @@ import java.util.Map; import java.util.Set; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; public class ModelCreationCreatorTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreatorTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreatorTest.java index d679c65e472ee3207cd00dd36018d3a90fff1fe5..1b7888fea56d0e9d2f94e2b1ad5bd8e45634d2ab 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreatorTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SampleCreatorTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.pdxfinder.dataloaders.updog.TSV; +import org.pdxfinder.TSV; import org.pdxfinder.graph.dao.Sample; import org.pdxfinder.graph.dao.Tissue; import org.pdxfinder.graph.dao.TumorType; @@ -15,8 +15,7 @@ import tech.tablesaw.api.Table; import java.util.Map; import java.util.Set; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class SampleCreatorTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreatorTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreatorTest.java index acc62f8e7b46273343e626b9391d463f7649ca39..431d34e81de63b8bf4c8517df062138ec4be54ed 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreatorTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/domainobjectcreation/SpecimenCreatorTest.java @@ -5,19 +5,15 @@ import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.pdxfinder.dataloaders.updog.TSV; -import org.pdxfinder.graph.dao.EngraftmentMaterial; -import org.pdxfinder.graph.dao.EngraftmentSite; -import org.pdxfinder.graph.dao.EngraftmentType; -import org.pdxfinder.graph.dao.HostStrain; -import org.pdxfinder.graph.dao.Specimen; +import org.pdxfinder.TSV; +import org.pdxfinder.graph.dao.*; import tech.tablesaw.api.Row; import tech.tablesaw.api.Table; import java.util.Map; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; public class SpecimenCreatorTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporterTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporterTest.java index ec9dda43b7312e681da5845d8f28d01734eddf33..d7969489312f92c06627f17fb59a676cdb3e0ab9 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporterTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/ErrorReporterTest.java @@ -1,15 +1,15 @@ package org.pdxfinder.dataloaders.updog.tablevalidation; import org.junit.Test; -import org.mockito.Mock; -import org.pdxfinder.dataloaders.updog.tablevalidation.error.*; -import org.slf4j.Logger; +import org.pdxfinder.dataloaders.updog.tablevalidation.error.EmptyValueError; +import org.pdxfinder.dataloaders.updog.tablevalidation.error.EmptyValueErrorCreator; +import org.pdxfinder.dataloaders.updog.tablevalidation.error.ValidationError; import tech.tablesaw.api.Table; import java.util.ArrayList; import java.util.List; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class ErrorReporterTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreatorTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreatorTest.java index 7dbddf5ea21d48af218d2c113efb7dc6000cd6cd..9ae52913ab60e45798c7e6c974723078f713565d 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreatorTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/BrokenRelationErrorCreatorTest.java @@ -7,14 +7,11 @@ import org.pdxfinder.dataloaders.updog.tablevalidation.TableSetSpecification; import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; public class BrokenRelationErrorCreatorTest { diff --git a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/EmptyValueErrorCreatorTest.java b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/EmptyValueErrorCreatorTest.java index 753c7b2394a691591cc08ec964fe7c05db5ecb09..79b00b1740e88c4aa9a52f89661b88ab7d2323bc 100644 --- a/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/EmptyValueErrorCreatorTest.java +++ b/indexer/src/test/java/org/pdxfinder/dataloaders/updog/tablevalidation/error/EmptyValueErrorCreatorTest.java @@ -10,16 +10,12 @@ import org.pdxfinder.dataloaders.updog.tablevalidation.TableSetSpecification; import tech.tablesaw.api.StringColumn; import tech.tablesaw.api.Table; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class EmptyValueErrorCreatorTest { diff --git a/indexer/src/test/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTermsTest.java b/indexer/src/test/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTermsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d78efb3d2faac5a734b7256cc12c99d3e6436619 --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/mapping/LinkTreatmentsToNCITTermsTest.java @@ -0,0 +1,74 @@ +package org.pdxfinder.mapping; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.OntologyTerm; +import org.pdxfinder.graph.dao.Treatment; +import org.pdxfinder.rdbms.dao.MappingEntity; +import org.pdxfinder.services.DataImportService; +import org.pdxfinder.services.MappingService; +import org.springframework.boot.test.mock.mockito.MockBean; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.*; + +public class LinkTreatmentsToNCITTermsTest extends BaseTest { + + @MockBean + private MappingService mappingService; + @MockBean + private DataImportService dataImportService; + + LinkTreatmentsToNCITTerms linkTreatmentsToNCITTerms; + + + @Before + public void init(){ + linkTreatmentsToNCITTerms = new LinkTreatmentsToNCITTerms(mappingService, dataImportService); + } + + + @Test + public void Given_Treatments_When_AddRelationshipToTreatments_Then_NewRelationshipIsPresent(){ + when(mappingService.getTreatmentMapping(any(), any())).thenReturn(getMappingEntity()); + when(dataImportService.findOntologyTermByUrl(any())).thenReturn(getOntologyTerm()); + + List<Treatment> treatments = getTreatments(); + linkTreatmentsToNCITTerms.addRelationshipToTreatments(treatments, "DS"); + Assert.assertEquals("otlabel1",treatments.get(0).getTreatmentToOntologyRelationship().getOntologyTerm().getLabel()); + + } + + + + private MappingEntity getMappingEntity(){ + + MappingEntity me = new MappingEntity(); + me.setJustification(""); + me.setMapType("direct"); + me.setMappedTermLabel("label1"); + + return me; + } + + private OntologyTerm getOntologyTerm(){ + OntologyTerm ot = new OntologyTerm(); + ot.setLabel("otlabel1"); + ot.setUrl("url1"); + return ot; + } + + private List<Treatment> getTreatments(){ + + List<Treatment> treatments = new ArrayList<>(); + + Treatment t1 = new Treatment("drug1"); + treatments.add(t1); + + return treatments; + } +} diff --git a/indexer/src/test/java/org/pdxfinder/postload/DataProjectionTest.java b/indexer/src/test/java/org/pdxfinder/postload/DataProjectionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..697841d2d5d7bb5819e2f3b8eaa3abb76718ab53 --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/postload/DataProjectionTest.java @@ -0,0 +1,178 @@ +package org.pdxfinder.postload; + +import org.apache.commons.collections4.map.HashedMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.*; +import org.pdxfinder.services.DataImportService; +import org.pdxfinder.services.DrugService; + +import org.springframework.boot.test.mock.mockito.MockBean; +import static org.mockito.Mockito.*; + +import java.util.*; + + +public class DataProjectionTest extends BaseTest { + + + CreateDataProjections createDataProjections; + + @MockBean + DataImportService dataImportService; + + @MockBean + DrugService drugService; + + + @Before + public void init() { + + createDataProjections = new CreateDataProjections(dataImportService, drugService); + + + } + + @Test + public void given_HashMapDP_when_saveDP_then_Saved(){ + createDataProjections.setCytogeneticsDP(getTwoKeyData()); + createDataProjections.setMutatedPlatformMarkerVariantModelDP(getThreeKeyData()); + createDataProjections.setModelDrugResponseDP(getTwoKeyData()); + createDataProjections.setImmunoHistoChemistryDP(getTwoKeyData()); + createDataProjections.setCopyNumberAlterationDP(getOneKeyData()); + createDataProjections.setExpressionDP(getTwoKeyData()); + createDataProjections.setDrugDosingDP(getOneKeyData()); + createDataProjections.setPatientTreatmentDP(getOneKeyData()); + createDataProjections.setFrequentlyMutatedMarkersDP(new ArrayList<>()); + createDataProjections.setExpressionDP(getTwoKeyData()); + createDataProjections.setDataAvailableDP(new HashedMap<>()); + createDataProjections.setFrequentlyMutatedMarkersDP(new ArrayList<>()); + + when(dataImportService.saveDataProjection(any())).thenAnswer(i -> i.getArguments()[0]); + when(dataImportService.findDataProjectionByLabel(any())).thenReturn(null); + + createDataProjections.saveDataProjections(); + + Assert.assertEquals("cytogenetics", createDataProjections.saveDP("cytogenetics", + createDataProjections.getCytogeneticsDP()).getLabel()); + Assert.assertEquals("copy number alteration", createDataProjections.saveDP("copy number alteration", + createDataProjections.getCopyNumberAlterationDP()).getLabel()); + Assert.assertEquals("expression", createDataProjections.saveDP("expression", + createDataProjections.getExpressionDP()).getLabel()); + Assert.assertEquals("PlatformMarkerVariantModel", createDataProjections.saveDP("PlatformMarkerVariantModel", + createDataProjections.getMutatedPlatformMarkerVariantModelDP()).getLabel()); + Assert.assertEquals("ModelDrugData", createDataProjections.saveDP("ModelDrugData", + createDataProjections.getModelDrugResponseDP()).getLabel()); + Assert.assertEquals("breast cancer markers", createDataProjections.saveDP("breast cancer markers", + createDataProjections.getImmunoHistoChemistryDP()).getLabel()); + Assert.assertEquals("drug dosing counter", createDataProjections.saveDP("drug dosing counter", + createDataProjections.getDrugDosingDP()).getLabel()); + Assert.assertEquals("patient treatment", createDataProjections.saveDP("patient treatment", + createDataProjections.getPatientTreatmentDP()).getLabel()); + Assert.assertEquals("MarkerVariant", createDataProjections.saveDP("MarkerVariant", + createDataProjections.getMutatedMarkerVariantDP()).getLabel()); + Assert.assertEquals("data available", createDataProjections.saveDP("data available", + createDataProjections.getDataAvailableDP()).getLabel()); + Assert.assertEquals("frequently mutated genes", createDataProjections.saveDP("frequently mutated genes", + createDataProjections.getFrequentlyMutatedMarkersDP()).getLabel()); + } + + @Test + public void given_Json_when_jsonKeyIsNull_then_ExceptionIsThrown(){ + Map<String, Long> map = new HashedMap<>(); + map.put(null, new Long(1)); + Assert.assertEquals("", createDataProjections.createJsonString(map)); + + } + + @Test + public void given_TreatmentSummary_when_Process_then_MapIsPopulated(){ + TreatmentSummary ts = getTreatmentSummary(); + createDataProjections.processModelDrugs(new Long(1), ts); + Assert.assertEquals(true,createDataProjections.getModelDrugResponseDP().containsKey("label5regimen")); + Assert.assertEquals(true,createDataProjections.getModelDrugResponseDP().containsKey("label1 and label2")); + } + + private Map<String, Set<Long>> getOneKeyData(){ + + Set<Long> modelIds = new HashSet<>(); + modelIds.add(new Long(1)); + Map<String, Set<Long>> map1 = new HashMap<>(); + map1.put("key1", modelIds); + return map1; + } + + private Map<String, Map<String, Set<Long>>> getTwoKeyData(){ + + Set<Long> modelIds = new HashSet<>(); + modelIds.add(new Long(1)); + Map<String, Set<Long>> map2 = new HashMap<>(); + Map<String, Map<String, Set<Long>>> map1 = new HashMap<>(); + map2.put("key2", modelIds); + map1.put("key1", map2); + return map1; + } + + private Map<String, Map<String, Map<String, Set<Long>>>> getThreeKeyData(){ + + Set<Long> modelIds = new HashSet<>(); + modelIds.add(new Long(1)); + Map<String, Set<Long>> map3 = new HashMap<>(); + Map<String, Map<String, Set<Long>>> map2 = new HashMap<>(); + Map<String, Map<String, Map<String, Set<Long>>>> map1 = new HashMap<>(); + map3.put("key3",modelIds); + map2.put("key2", map3); + map1.put("key1", map2); + return map1; + } + + + private TreatmentSummary getTreatmentSummary(){ + TreatmentSummary ts = new TreatmentSummary(); + TreatmentProtocol tp1 = new TreatmentProtocol(); + TreatmentProtocol tp2 = new TreatmentProtocol(); + Response response = new Response(); + response.setDescription("description"); + tp1.setResponse(response); + tp2.setResponse(response); + TreatmentComponent tc1 = new TreatmentComponent(); + TreatmentComponent tc2 = new TreatmentComponent(); + TreatmentComponent tc3 = new TreatmentComponent(); + Treatment t1 = new Treatment("regimendrug1"); + Treatment t2 = new Treatment("drug2"); + Treatment t3 = new Treatment("drug3"); + TreatmentToOntologyRelationship ttor1 = new TreatmentToOntologyRelationship(); + TreatmentToOntologyRelationship ttor2 = new TreatmentToOntologyRelationship(); + TreatmentToOntologyRelationship ttor3 = new TreatmentToOntologyRelationship(); + OntologyTerm ot1 = new OntologyTerm("url1", "label1"); + OntologyTerm ot2 = new OntologyTerm("url2", "label2"); + OntologyTerm ot3 = new OntologyTerm("url3", "label3"); + OntologyTerm ot4 = new OntologyTerm("url4", "label4"); + ot1.setType("Drug"); + ot2.setType("Drug"); + ot3.setType("Drug"); + ot4.setType("Drug"); + OntologyTerm regimen = new OntologyTerm("url5", "label5regimen"); + regimen.setType("treatment regimen"); + regimen.addSubclass(ot3); + regimen.addSubclass(ot4); + t1.setTreatmentToOntologyRelationship(ttor1); + ttor1.setOntologyTerm(regimen); + tc1.setTreatment(t1); + tp1.addTreatmentComponent(tc1); + ts.addTreatmentProtocol(tp1); + tc2.setTreatment(t2); + tc3.setTreatment(t3); + t2.setTreatmentToOntologyRelationship(ttor2); + t3.setTreatmentToOntologyRelationship(ttor3); + ttor2.setOntologyTerm(ot1); + ttor3.setOntologyTerm(ot2); + tp2.addTreatmentComponent(tc2); + tp2.addTreatmentComponent(tc3); + ts.addTreatmentProtocol(tp2); + return ts; + } + +} diff --git a/indexer/src/test/java/org/pdxfinder/postload/SetDataVisibilityTest.java b/indexer/src/test/java/org/pdxfinder/postload/SetDataVisibilityTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9e4f5055c745882e970b1c8321e4bd7b760f6c45 --- /dev/null +++ b/indexer/src/test/java/org/pdxfinder/postload/SetDataVisibilityTest.java @@ -0,0 +1,60 @@ +package org.pdxfinder.postload; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.pdxfinder.BaseTest; +import org.pdxfinder.graph.dao.MolecularCharacterization; +import org.pdxfinder.services.DataImportService; +import org.springframework.boot.test.mock.mockito.MockBean; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.*; + +public class SetDataVisibilityTest extends BaseTest { + + @MockBean + DataImportService dataImportService; + + SetDataVisibility setDataVisibility; + + @Before + public void init(){ + + setDataVisibility = new SetDataVisibility(dataImportService); + } + + @Test + public void Given_MolecularCharacterizations_When_DisablingVisibility_Then_VisibilityDisabled(){ + + List<MolecularCharacterization> molchars = getMolchars(); + setDataVisibility.disableVisibility(molchars); + Assert.assertEquals(false, molchars.get(0).isVisible()); + } + + @Test + public void Given_DataSource_When_ApplyRules_Then_RulesApplied(){ + + when(dataImportService.findMolcharNumberByDataSource("TEST")).thenReturn(2); + when(dataImportService.findMolcharByDataSourceSkipLimit("TEST", 0, 50)).thenReturn(getMolchars()); + + setDataVisibility.applyDataVisibilityRules("TEST"); + List<MolecularCharacterization> molcharList = getMolchars(); + verify(dataImportService, times(1)).saveMolecularCharacterizations(any()); + } + + + private List<MolecularCharacterization> getMolchars(){ + + MolecularCharacterization mc1 = new MolecularCharacterization(); + MolecularCharacterization mc2 = new MolecularCharacterization(); + List<MolecularCharacterization> list = new ArrayList<>(); + + list.add(mc1); + list.add(mc2); + return list; + } + +} diff --git a/package-list b/package-list deleted file mode 100644 index 937c43e86aeefdba2791207655a608f51ff026d0..0000000000000000000000000000000000000000 --- a/package-list +++ /dev/null @@ -1 +0,0 @@ -org.sprintell diff --git a/web/pom.xml b/web/pom.xml index 4c79da9c6bff4911f24f65a263e6a50fda8faca9..21c72bcae63c5769cb3db73990f40d033bd57aaa 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -25,11 +25,6 @@ <artifactId>spring-boot-starter-web</artifactId> </dependency> - <dependency> - <groupId>org.springframework.boot</groupId> - <artifactId>spring-boot-starter-thymeleaf</artifactId> - </dependency> - <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> @@ -46,6 +41,17 @@ <artifactId>spring-boot-starter-security</artifactId> </dependency> + <dependency> + <groupId>org.neo4j</groupId> + <artifactId>neo4j-ogm-bolt-driver</artifactId> + <version>3.1.20</version> + </dependency> + <dependency> + <!-- WARNING, do not update db engine (stable: 1.4.197) cause compatibility issues, see https://github.com/h2database/h2database/issues/2078 --> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>1.4.197</version> + </dependency> </dependencies> <build> diff --git a/web/src/main/java/org/pdxfinder/web/controllers/AjaxController.java b/web/src/main/java/org/pdxfinder/web/controllers/AjaxController.java index 3a8e39fb690a40c8ab05ee03310c656e3d643ca9..ee82a1daccba8f1467041c9c6abf89a65ac23d32 100644 --- a/web/src/main/java/org/pdxfinder/web/controllers/AjaxController.java +++ b/web/src/main/java/org/pdxfinder/web/controllers/AjaxController.java @@ -10,14 +10,13 @@ import org.pdxfinder.services.pdf.Label; import org.pdxfinder.services.pdf.PdfHelper; import org.pdxfinder.services.pdf.Report; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Arrays; +import java.util.*; /* * Created by csaba on 03/05/2018. @@ -178,7 +177,7 @@ public class AjaxController { @GetMapping("/getmoleculardata/{molcharId}") public MolecularDataTableDTO getMolecularTableData(@PathVariable String molcharId){ - return detailsService.getMolecularDataTable(molcharId); + return detailsService.getMolecularDataTable(molcharId, false); } diff --git a/web/src/main/java/org/pdxfinder/web/controllers/CBioController.java b/web/src/main/java/org/pdxfinder/web/controllers/CBioController.java index 3358354ce3094b5ec2e5c6edccb20b2176ab45f3..2dcb670839d78a45084e3feb30dd8a89a82c2611 100644 --- a/web/src/main/java/org/pdxfinder/web/controllers/CBioController.java +++ b/web/src/main/java/org/pdxfinder/web/controllers/CBioController.java @@ -60,10 +60,11 @@ public class CBioController { @RequestParam("project") Optional<List<String>> project, @RequestParam("data_available") Optional<List<String>> data_available, @RequestParam("breast_cancer_markers") Optional<List<String>> breast_cancer_markers, - @RequestParam( "access_modalities" ) Optional<List<String>> access_modalities, + @RequestParam("access_modalities") Optional<List<String>> access_modalities, @RequestParam("copy_number_alteration") Optional<List<String>> copy_number_alteration, @RequestParam("gene_expression") Optional<List<String>> gene_expression, @RequestParam("cytogenetics") Optional<List<String>> cytogenetics, + @RequestParam("model_id") Optional<List<String>> model_id, Login login ) { @@ -86,11 +87,12 @@ public class CBioController { logger.info("copy_number_alteration" + copy_number_alteration.toString()); logger.info("gene_expression" + gene_expression.toString()); logger.info("cytogenetics" + cytogenetics.toString()); + logger.info("model_id" + cytogenetics.toString()); List<String> ids = captureIDs(query, datasource, diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, sample_tumor_type, mutation, drug, project, - data_available, breast_cancer_markers, access_modalities, copy_number_alteration, gene_expression, cytogenetics); + data_available, breast_cancer_markers, access_modalities, copy_number_alteration, gene_expression, cytogenetics, model_id); String tmp_list = createTmpList(ids); @@ -246,7 +248,8 @@ public class CBioController { Optional<List<String>> access_modalities, Optional<List<String>> copy_number_alteration, Optional<List<String>> gene_expressions, - Optional<List<String>> cytogenetics) { + Optional<List<String>> cytogenetics, + Optional<List<String>> model_id) { /* DS: old ExportDTO eDTO = searchService.export(query, datasource, @@ -265,7 +268,7 @@ public class CBioController { ExportDTO eDTO = searchService.export(query, datasource, diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, sample_tumor_type, mutation, drug, project, data_available, breast_cancer_markers, access_modalities, - copy_number_alteration, gene_expressions, cytogenetics); + copy_number_alteration, gene_expressions, cytogenetics, model_id); return eDTO.getResults().stream().map(ModelForQuery::getExternalId).collect(Collectors.toList()); } diff --git a/web/src/main/java/org/pdxfinder/web/controllers/DetailsController.java b/web/src/main/java/org/pdxfinder/web/controllers/DetailsController.java index 2db52c89563a0a9e8812633ef7bec128b2dff133..ad2928fac8601f3f06be4804ded006bb0cb49a3c 100644 --- a/web/src/main/java/org/pdxfinder/web/controllers/DetailsController.java +++ b/web/src/main/java/org/pdxfinder/web/controllers/DetailsController.java @@ -9,12 +9,16 @@ import org.pdxfinder.services.pdf.PdfHelper; import org.pdxfinder.services.pdf.Report; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.*; +import java.util.List; +import java.util.Map; @Controller @@ -51,11 +55,11 @@ public class DetailsController { @PathVariable String molcharType, @PathVariable String molcharId) throws IOException { - List<Map<String, Object>> molecularDataRowDTOS = detailsService.getMolecularDataTable(molcharId).getMolecularDataCsv(); + List<Map<String, Object>> molecularDataRowDTOS = detailsService.getMolecularDataTable(molcharId, true).getMolecularDataCsv(); String output = utilityService.serializeToCsvWithIncludeNonEmpty(molecularDataRowDTOS); response.setContentType("application/octet-stream"); - response.setHeader("Content-Disposition", String.format("attachment; filename=dataportal.europdx.eu_%s_%s_%s.csv",dataSrc, modelId, molcharType)); + response.setHeader("Content-Disposition", String.format("attachment; filename=pdxfinder.org_%s_%s_%s.csv",dataSrc, modelId, molcharType)); response.getOutputStream().flush(); return output; } diff --git a/web/src/main/java/org/pdxfinder/web/controllers/SearchController.java b/web/src/main/java/org/pdxfinder/web/controllers/SearchController.java index 43f63eb39d589792a0a5667ee0a8b3846ad005eb..11fe1453c5db5992f240b10b8f1102a66e650aae 100644 --- a/web/src/main/java/org/pdxfinder/web/controllers/SearchController.java +++ b/web/src/main/java/org/pdxfinder/web/controllers/SearchController.java @@ -8,8 +8,6 @@ import org.pdxfinder.services.ds.ModelForQueryExport; import org.pdxfinder.services.dto.ExportDTO; import org.pdxfinder.web.model.Identity; import org.pdxfinder.web.model.Login; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @@ -29,7 +27,6 @@ import java.util.stream.Collectors; public class SearchController { private SearchService searchService; - private Logger logger = LoggerFactory.getLogger(SearchController.class); public SearchController(SearchService searchService) { @@ -54,16 +51,19 @@ public class SearchController { @RequestParam("project") Optional<List<String>> project, @RequestParam("data_available") Optional<List<String>> data_available, @RequestParam("breast_cancer_markers") Optional<List<String>> breast_cancer_markers, - @RequestParam("breast_cancer_markers") Optional<List<String>> access_modalities, + @RequestParam("access_modalities") Optional<List<String>> access_modalities, @RequestParam("copy_number_alteration") Optional<List<String>> copy_number_alteration, @RequestParam("gene_expression") Optional<List<String>> gene_expression, - @RequestParam("cytogenetics") Optional<List<String>> cytogenetics - ) { + @RequestParam("cytogenetics") Optional<List<String>> cytogenetics, + @RequestParam("model_id") Optional<List<String>> model_id + + ) { + ExportDTO eDTO = searchService.export(query, datasource, diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, sample_tumor_type, mutation, drug, project, data_available, breast_cancer_markers, access_modalities, copy_number_alteration, - gene_expression, cytogenetics); + gene_expression, cytogenetics, model_id); Set<ModelForQueryExport> exportResults = eDTO.getResults().stream().map(ModelForQueryExport::new).collect(Collectors.toSet()); @@ -107,21 +107,21 @@ public class SearchController { @RequestParam("project") Optional<List<String>> project, @RequestParam("data_available") Optional<List<String>> data_available, @RequestParam("breast_cancer_markers") Optional<List<String>> breast_cancer_markers, - @RequestParam( "access_modalities" ) Optional<List<String>> access_modalities, + @RequestParam("access_modalities") Optional<List<String>> access_modalities, @RequestParam("copy_number_alteration") Optional<List<String>> copy_number_alteration, @RequestParam("gene_expression") Optional<List<String>> gene_expression, @RequestParam("cytogenetics") Optional<List<String>> cytogenetics, + @RequestParam("model_id") Optional<List<String>> model_id, + @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "size", defaultValue = "10") Integer size, Login login, Identity identity){ - logger.info(login.toString()); - String authPass = System.getenv("AUTH_PASS"); if (authPass == null) authPass = ""; if (!login.isAuthorized() && !authPass.equals("1")) { - model.addAttribute("returnTo", "/search"); + model.addAttribute("returnTo", "/search"); model.addAttribute("identityName", null); return "authentication"; } @@ -134,16 +134,8 @@ public class SearchController { model.addAttribute("websearch", searchService.webSearch(query, datasource, diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, sample_tumor_type, mutation, drug, project, data_available, breast_cancer_markers, access_modalities, copy_number_alteration, gene_expression, - cytogenetics, page, size)); - - // model.addAttribute("websearch", searchService.webSearch(query, datasource, - // diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, - // sample_tumor_type, mutation, drug, project, data_available, breast_cancer_markers, copy_number_alteration, page, size)); - + cytogenetics, model_id, page, size)); - // model.addAttribute("websearch", searchService.webSearch(query, datasource, - // diagnosis, patient_age, patient_treatment, patient_treatment_status, patient_gender, sample_origin_tissue, cancer_system, - // sample_tumor_type, mutation, drug, project, data_available, breast_cancer_markers, access_modalities, copy_number_alteration, page, size)); return "search"; } diff --git a/web/src/main/resources/application.properties b/web/src/main/resources/application.properties index b3ff60513fb9a4edef6dbeb11a1505db8d408a0a..b7985c1bd178ebe2a7610227fc0176960bffe5d4 100644 --- a/web/src/main/resources/application.properties +++ b/web/src/main/resources/application.properties @@ -1,28 +1,28 @@ -management.security.enabled=false -#spring.data.rest.base-path=/api spring.jackson.serialization.indent_output=true # Enable certain actuator endpoints -endpoints.env.enabled=true -endpoints.env.sensitive=false +management.endpoint.env.enabled=true +management.endpoints.web.base-path=/manage +management.endpoints.web.exposure.include=env # Default logging level to INFO logging.level.=INFO # Tone down Spring extra-chatty components logging.level.org.springframework.boot.autoconfigure.logging=ERROR -logging.level.org.springframework.data.neo4j.mapping.Neo4jPersistentProperty=ERROR +logging.level.org.springframework.data.neo4j.mapping.Neo4jPersistentProperty=ERROR spring.data.neo4j.username=neo4j spring.data.neo4j.password=neo5j -spring.data.neo4j.uri=http://neo4j:7474 -#spring.data.neo4j.uri=http://dataportal-beta.edirex.ics.muni.cz:7474 - +spring.data.neo4j.uri=bolt://neo4j +#spring.data.neo4j.uri=bolt://dataportal-beta.edirex.ics.muni.cz server.error.whitelabel.enabled=false spring.thymeleaf.cache=false -server.context-path=/data +server.servlet.context-path=/data + #mappings file containing diagnosis to NCIT links mappings.diagnosis.file=file.json +mappings.mappedTermUrl= edirex.datahubapi=GITLAB-CI edirex.k8sapi=GITLAB-CI @@ -33,12 +33,9 @@ edirex.debugmode=false #edirex.debugmode=true -mappings.mappedTermUrl= - -pdxfinder.root.dir= - -management.health.mail.enabled=false data-dir= +pdxfinder.root.dir= data.directory= +management.health.mail.enabled=false diff --git a/web/src/main/resources/static/css/validationLog.css b/web/src/main/resources/static/css/validationLog.css new file mode 100644 index 0000000000000000000000000000000000000000..ca5381c6c208b8831be40593b79e1904f42f3bae --- /dev/null +++ b/web/src/main/resources/static/css/validationLog.css @@ -0,0 +1,19 @@ +@import url("app.css"); + +body { + background: #fff; + padding: 2em; +} + +.header { + font-weight: bold; + text-transform: uppercase; +} + +.error > .Level{ + color: darkred; +} + +.info { + color: #3b5999; +} \ No newline at end of file diff --git a/web/src/main/resources/static/js/chart.bundle.js b/web/src/main/resources/static/js/chart.bundle.js deleted file mode 100644 index bf6ee755c4a3683e7056e051c98034ab2c582cd1..0000000000000000000000000000000000000000 --- a/web/src/main/resources/static/js/chart.bundle.js +++ /dev/null @@ -1,18962 +0,0 @@ -/*! - * Chart.js - * http://chartjs.org/ - * Version: 2.7.3 - * - * Copyright 2018 Chart.js Contributors - * Released under the MIT license - * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md - */ -(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.Chart = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ -/* MIT license */ -var colorNames = require(5); - -module.exports = { - getRgba: getRgba, - getHsla: getHsla, - getRgb: getRgb, - getHsl: getHsl, - getHwb: getHwb, - getAlpha: getAlpha, - - hexString: hexString, - rgbString: rgbString, - rgbaString: rgbaString, - percentString: percentString, - percentaString: percentaString, - hslString: hslString, - hslaString: hslaString, - hwbString: hwbString, - keyword: keyword -} - -function getRgba(string) { - if (!string) { - return; - } - var abbr = /^#([a-fA-F0-9]{3})$/i, - hex = /^#([a-fA-F0-9]{6})$/i, - rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - keyword = /(\w+)/; - - var rgb = [0, 0, 0], - a = 1, - match = string.match(abbr); - if (match) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i] + match[i], 16); - } - } - else if (match = string.match(hex)) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); - } - } - else if (match = string.match(rgba)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i + 1]); - } - a = parseFloat(match[4]); - } - else if (match = string.match(per)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); - } - a = parseFloat(match[4]); - } - else if (match = string.match(keyword)) { - if (match[1] == "transparent") { - return [0, 0, 0, 0]; - } - rgb = colorNames[match[1]]; - if (!rgb) { - return; - } - } - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = scale(rgb[i], 0, 255); - } - if (!a && a != 0) { - a = 1; - } - else { - a = scale(a, 0, 1); - } - rgb[3] = a; - return rgb; -} - -function getHsla(string) { - if (!string) { - return; - } - var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hsl); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - s = scale(parseFloat(match[2]), 0, 100), - l = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, s, l, a]; - } -} - -function getHwb(string) { - if (!string) { - return; - } - var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hwb); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - w = scale(parseFloat(match[2]), 0, 100), - b = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, w, b, a]; - } -} - -function getRgb(string) { - var rgba = getRgba(string); - return rgba && rgba.slice(0, 3); -} - -function getHsl(string) { - var hsla = getHsla(string); - return hsla && hsla.slice(0, 3); -} - -function getAlpha(string) { - var vals = getRgba(string); - if (vals) { - return vals[3]; - } - else if (vals = getHsla(string)) { - return vals[3]; - } - else if (vals = getHwb(string)) { - return vals[3]; - } -} - -// generators -function hexString(rgb) { - return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1]) - + hexDouble(rgb[2]); -} - -function rgbString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return rgbaString(rgba, alpha); - } - return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; -} - -function rgbaString(rgba, alpha) { - if (alpha === undefined) { - alpha = (rgba[3] !== undefined ? rgba[3] : 1); - } - return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] - + ", " + alpha + ")"; -} - -function percentString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return percentaString(rgba, alpha); - } - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - - return "rgb(" + r + "%, " + g + "%, " + b + "%)"; -} - -function percentaString(rgba, alpha) { - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; -} - -function hslString(hsla, alpha) { - if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { - return hslaString(hsla, alpha); - } - return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; -} - -function hslaString(hsla, alpha) { - if (alpha === undefined) { - alpha = (hsla[3] !== undefined ? hsla[3] : 1); - } - return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " - + alpha + ")"; -} - -// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax -// (hwb have alpha optional & 1 is default value) -function hwbString(hwb, alpha) { - if (alpha === undefined) { - alpha = (hwb[3] !== undefined ? hwb[3] : 1); - } - return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" - + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; -} - -function keyword(rgb) { - return reverseNames[rgb.slice(0, 3)]; -} - -// helpers -function scale(num, min, max) { - return Math.min(Math.max(min, num), max); -} - -function hexDouble(num) { - var str = num.toString(16).toUpperCase(); - return (str.length < 2) ? "0" + str : str; -} - - -//create a list of reverse color names -var reverseNames = {}; -for (var name in colorNames) { - reverseNames[colorNames[name]] = name; -} - -},{"5":5}],2:[function(require,module,exports){ -/* MIT license */ -var convert = require(4); -var string = require(1); - -var Color = function (obj) { - if (obj instanceof Color) { - return obj; - } - if (!(this instanceof Color)) { - return new Color(obj); - } - - this.valid = false; - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - }; - - // parse Color() argument - var vals; - if (typeof obj === 'string') { - vals = string.getRgba(obj); - if (vals) { - this.setValues('rgb', vals); - } else if (vals = string.getHsla(obj)) { - this.setValues('hsl', vals); - } else if (vals = string.getHwb(obj)) { - this.setValues('hwb', vals); - } - } else if (typeof obj === 'object') { - vals = obj; - if (vals.r !== undefined || vals.red !== undefined) { - this.setValues('rgb', vals); - } else if (vals.l !== undefined || vals.lightness !== undefined) { - this.setValues('hsl', vals); - } else if (vals.v !== undefined || vals.value !== undefined) { - this.setValues('hsv', vals); - } else if (vals.w !== undefined || vals.whiteness !== undefined) { - this.setValues('hwb', vals); - } else if (vals.c !== undefined || vals.cyan !== undefined) { - this.setValues('cmyk', vals); - } - } -}; - -Color.prototype = { - isValid: function () { - return this.valid; - }, - rgb: function () { - return this.setSpace('rgb', arguments); - }, - hsl: function () { - return this.setSpace('hsl', arguments); - }, - hsv: function () { - return this.setSpace('hsv', arguments); - }, - hwb: function () { - return this.setSpace('hwb', arguments); - }, - cmyk: function () { - return this.setSpace('cmyk', arguments); - }, - - rgbArray: function () { - return this.values.rgb; - }, - hslArray: function () { - return this.values.hsl; - }, - hsvArray: function () { - return this.values.hsv; - }, - hwbArray: function () { - var values = this.values; - if (values.alpha !== 1) { - return values.hwb.concat([values.alpha]); - } - return values.hwb; - }, - cmykArray: function () { - return this.values.cmyk; - }, - rgbaArray: function () { - var values = this.values; - return values.rgb.concat([values.alpha]); - }, - hslaArray: function () { - var values = this.values; - return values.hsl.concat([values.alpha]); - }, - alpha: function (val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues('alpha', val); - return this; - }, - - red: function (val) { - return this.setChannel('rgb', 0, val); - }, - green: function (val) { - return this.setChannel('rgb', 1, val); - }, - blue: function (val) { - return this.setChannel('rgb', 2, val); - }, - hue: function (val) { - if (val) { - val %= 360; - val = val < 0 ? 360 + val : val; - } - return this.setChannel('hsl', 0, val); - }, - saturation: function (val) { - return this.setChannel('hsl', 1, val); - }, - lightness: function (val) { - return this.setChannel('hsl', 2, val); - }, - saturationv: function (val) { - return this.setChannel('hsv', 1, val); - }, - whiteness: function (val) { - return this.setChannel('hwb', 1, val); - }, - blackness: function (val) { - return this.setChannel('hwb', 2, val); - }, - value: function (val) { - return this.setChannel('hsv', 2, val); - }, - cyan: function (val) { - return this.setChannel('cmyk', 0, val); - }, - magenta: function (val) { - return this.setChannel('cmyk', 1, val); - }, - yellow: function (val) { - return this.setChannel('cmyk', 2, val); - }, - black: function (val) { - return this.setChannel('cmyk', 3, val); - }, - - hexString: function () { - return string.hexString(this.values.rgb); - }, - rgbString: function () { - return string.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function () { - return string.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function () { - return string.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function () { - return string.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function () { - return string.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function () { - return string.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function () { - return string.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function () { - var rgb = this.values.rgb; - return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; - }, - - luminosity: function () { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function (color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05); - } - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function (color2) { - var contrastRatio = this.contrast(color2); - if (contrastRatio >= 7.1) { - return 'AAA'; - } - - return (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function () { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb; - var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function () { - return !this.dark(); - }, - - negate: function () { - var rgb = []; - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues('rgb', rgb); - return this; - }, - - lighten: function (ratio) { - var hsl = this.values.hsl; - hsl[2] += hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - darken: function (ratio) { - var hsl = this.values.hsl; - hsl[2] -= hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - saturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] += hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - desaturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] -= hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - whiten: function (ratio) { - var hwb = this.values.hwb; - hwb[1] += hwb[1] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - blacken: function (ratio) { - var hwb = this.values.hwb; - hwb[2] += hwb[2] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - greyscale: function () { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues('rgb', [val, val, val]); - return this; - }, - - clearer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha - (alpha * ratio)); - return this; - }, - - opaquer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha + (alpha * ratio)); - return this; - }, - - rotate: function (degrees) { - var hsl = this.values.hsl; - var hue = (hsl[0] + degrees) % 360; - hsl[0] = hue < 0 ? 360 + hue : hue; - this.setValues('hsl', hsl); - return this; - }, - - /** - * Ported from sass implementation in C - * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 - */ - mix: function (mixinColor, weight) { - var color1 = this; - var color2 = mixinColor; - var p = weight === undefined ? 0.5 : weight; - - var w = 2 * p - 1; - var a = color1.alpha() - color2.alpha(); - - var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - return this - .rgb( - w1 * color1.red() + w2 * color2.red(), - w1 * color1.green() + w2 * color2.green(), - w1 * color1.blue() + w2 * color2.blue() - ) - .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); - }, - - toJSON: function () { - return this.rgb(); - }, - - clone: function () { - // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, - // making the final build way to big to embed in Chart.js. So let's do it manually, - // assuming that values to clone are 1 dimension arrays containing only numbers, - // except 'alpha' which is a number. - var result = new Color(); - var source = this.values; - var target = result.values; - var value, type; - - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - value = source[prop]; - type = ({}).toString.call(value); - if (type === '[object Array]') { - target[prop] = value.slice(0); - } else if (type === '[object Number]') { - target[prop] = value; - } else { - console.error('unexpected color value:', value); - } - } - } - - return result; - } -}; - -Color.prototype.spaces = { - rgb: ['red', 'green', 'blue'], - hsl: ['hue', 'saturation', 'lightness'], - hsv: ['hue', 'saturation', 'value'], - hwb: ['hue', 'whiteness', 'blackness'], - cmyk: ['cyan', 'magenta', 'yellow', 'black'] -}; - -Color.prototype.maxes = { - rgb: [255, 255, 255], - hsl: [360, 100, 100], - hsv: [360, 100, 100], - hwb: [360, 100, 100], - cmyk: [100, 100, 100, 100] -}; - -Color.prototype.getValues = function (space) { - var values = this.values; - var vals = {}; - - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = values[space][i]; - } - - if (values.alpha !== 1) { - vals.a = values.alpha; - } - - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -}; - -Color.prototype.setValues = function (space, vals) { - var values = this.values; - var spaces = this.spaces; - var maxes = this.maxes; - var alpha = 1; - var i; - - this.valid = true; - - if (space === 'alpha') { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (i = 0; i < space.length; i++) { - values[space][i] = vals[space.charAt(i)]; - } - - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - - for (i = 0; i < space.length; i++) { - values[space][i] = vals[chans[i]]; - } - - alpha = vals.alpha; - } - - values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); - - if (space === 'alpha') { - return false; - } - - var capped; - - // cap values of the space prior converting all values - for (i = 0; i < space.length; i++) { - capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); - values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname !== space) { - values[sname] = convert[space][sname](values[space]); - } - } - - return true; -}; - -Color.prototype.setSpace = function (space, args) { - var vals = args[0]; - - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - - // color.rgb(10, 10, 10) - if (typeof vals === 'number') { - vals = Array.prototype.slice.call(args); - } - - this.setValues(space, vals); - return this; -}; - -Color.prototype.setChannel = function (space, index, val) { - var svalues = this.values[space]; - if (val === undefined) { - // color.red() - return svalues[index]; - } else if (val === svalues[index]) { - // color.red(color.red()) - return this; - } - - // color.red(100) - svalues[index] = val; - this.setValues(space, svalues); - - return this; -}; - -if (typeof window !== 'undefined') { - window.Color = Color; -} - -module.exports = Color; - -},{"1":1,"4":4}],3:[function(require,module,exports){ -/* MIT license */ - -module.exports = { - rgb2hsl: rgb2hsl, - rgb2hsv: rgb2hsv, - rgb2hwb: rgb2hwb, - rgb2cmyk: rgb2cmyk, - rgb2keyword: rgb2keyword, - rgb2xyz: rgb2xyz, - rgb2lab: rgb2lab, - rgb2lch: rgb2lch, - - hsl2rgb: hsl2rgb, - hsl2hsv: hsl2hsv, - hsl2hwb: hsl2hwb, - hsl2cmyk: hsl2cmyk, - hsl2keyword: hsl2keyword, - - hsv2rgb: hsv2rgb, - hsv2hsl: hsv2hsl, - hsv2hwb: hsv2hwb, - hsv2cmyk: hsv2cmyk, - hsv2keyword: hsv2keyword, - - hwb2rgb: hwb2rgb, - hwb2hsl: hwb2hsl, - hwb2hsv: hwb2hsv, - hwb2cmyk: hwb2cmyk, - hwb2keyword: hwb2keyword, - - cmyk2rgb: cmyk2rgb, - cmyk2hsl: cmyk2hsl, - cmyk2hsv: cmyk2hsv, - cmyk2hwb: cmyk2hwb, - cmyk2keyword: cmyk2keyword, - - keyword2rgb: keyword2rgb, - keyword2hsl: keyword2hsl, - keyword2hsv: keyword2hsv, - keyword2hwb: keyword2hwb, - keyword2cmyk: keyword2cmyk, - keyword2lab: keyword2lab, - keyword2xyz: keyword2xyz, - - xyz2rgb: xyz2rgb, - xyz2lab: xyz2lab, - xyz2lch: xyz2lch, - - lab2xyz: lab2xyz, - lab2rgb: lab2rgb, - lab2lch: lab2lch, - - lch2lab: lch2lab, - lch2xyz: lch2xyz, - lch2rgb: lch2rgb -} - - -function rgb2hsl(rgb) { - var r = rgb[0]/255, - g = rgb[1]/255, - b = rgb[2]/255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s, l; - - if (max == min) - h = 0; - else if (r == max) - h = (g - b) / delta; - else if (g == max) - h = 2 + (b - r) / delta; - else if (b == max) - h = 4 + (r - g)/ delta; - - h = Math.min(h * 60, 360); - - if (h < 0) - h += 360; - - l = (min + max) / 2; - - if (max == min) - s = 0; - else if (l <= 0.5) - s = delta / (max + min); - else - s = delta / (2 - max - min); - - return [h, s * 100, l * 100]; -} - -function rgb2hsv(rgb) { - var r = rgb[0], - g = rgb[1], - b = rgb[2], - min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s, v; - - if (max == 0) - s = 0; - else - s = (delta/max * 1000)/10; - - if (max == min) - h = 0; - else if (r == max) - h = (g - b) / delta; - else if (g == max) - h = 2 + (b - r) / delta; - else if (b == max) - h = 4 + (r - g) / delta; - - h = Math.min(h * 60, 360); - - if (h < 0) - h += 360; - - v = ((max / 255) * 1000) / 10; - - return [h, s, v]; -} - -function rgb2hwb(rgb) { - var r = rgb[0], - g = rgb[1], - b = rgb[2], - h = rgb2hsl(rgb)[0], - w = 1/255 * Math.min(r, Math.min(g, b)), - b = 1 - 1/255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -} - -function rgb2cmyk(rgb) { - var r = rgb[0] / 255, - g = rgb[1] / 255, - b = rgb[2] / 255, - c, m, y, k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - return [c * 100, m * 100, y * 100, k * 100]; -} - -function rgb2keyword(rgb) { - return reverseKeywords[JSON.stringify(rgb)]; -} - -function rgb2xyz(rgb) { - var r = rgb[0] / 255, - g = rgb[1] / 255, - b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y *100, z * 100]; -} - -function rgb2lab(rgb) { - var xyz = rgb2xyz(rgb), - x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function rgb2lch(args) { - return lab2lch(rgb2lab(args)); -} - -function hsl2rgb(hsl) { - var h = hsl[0] / 360, - s = hsl[1] / 100, - l = hsl[2] / 100, - t1, t2, t3, rgb, val; - - if (s == 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) - t2 = l * (1 + s); - else - t2 = l + s - l * s; - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * - (i - 1); - t3 < 0 && t3++; - t3 > 1 && t3--; - - if (6 * t3 < 1) - val = t1 + (t2 - t1) * 6 * t3; - else if (2 * t3 < 1) - val = t2; - else if (3 * t3 < 2) - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - else - val = t1; - - rgb[i] = val * 255; - } - - return rgb; -} - -function hsl2hsv(hsl) { - var h = hsl[0], - s = hsl[1] / 100, - l = hsl[2] / 100, - sv, v; - - if(l === 0) { - // no need to do calc on black - // also avoids divide by 0 error - return [0, 0, 0]; - } - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - v = (l + s) / 2; - sv = (2 * s) / (l + s); - return [h, sv * 100, v * 100]; -} - -function hsl2hwb(args) { - return rgb2hwb(hsl2rgb(args)); -} - -function hsl2cmyk(args) { - return rgb2cmyk(hsl2rgb(args)); -} - -function hsl2keyword(args) { - return rgb2keyword(hsl2rgb(args)); -} - - -function hsv2rgb(hsv) { - var h = hsv[0] / 60, - s = hsv[1] / 100, - v = hsv[2] / 100, - hi = Math.floor(h) % 6; - - var f = h - Math.floor(h), - p = 255 * v * (1 - s), - q = 255 * v * (1 - (s * f)), - t = 255 * v * (1 - (s * (1 - f))), - v = 255 * v; - - switch(hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -} - -function hsv2hsl(hsv) { - var h = hsv[0], - s = hsv[1] / 100, - v = hsv[2] / 100, - sl, l; - - l = (2 - s) * v; - sl = s * v; - sl /= (l <= 1) ? l : 2 - l; - sl = sl || 0; - l /= 2; - return [h, sl * 100, l * 100]; -} - -function hsv2hwb(args) { - return rgb2hwb(hsv2rgb(args)) -} - -function hsv2cmyk(args) { - return rgb2cmyk(hsv2rgb(args)); -} - -function hsv2keyword(args) { - return rgb2keyword(hsv2rgb(args)); -} - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -function hwb2rgb(hwb) { - var h = hwb[0] / 360, - wh = hwb[1] / 100, - bl = hwb[2] / 100, - ratio = wh + bl, - i, v, f, n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - if ((i & 0x01) != 0) { - f = 1 - f; - } - n = wh + f * (v - wh); // linear interpolation - - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -} - -function hwb2hsl(args) { - return rgb2hsl(hwb2rgb(args)); -} - -function hwb2hsv(args) { - return rgb2hsv(hwb2rgb(args)); -} - -function hwb2cmyk(args) { - return rgb2cmyk(hwb2rgb(args)); -} - -function hwb2keyword(args) { - return rgb2keyword(hwb2rgb(args)); -} - -function cmyk2rgb(cmyk) { - var c = cmyk[0] / 100, - m = cmyk[1] / 100, - y = cmyk[2] / 100, - k = cmyk[3] / 100, - r, g, b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - return [r * 255, g * 255, b * 255]; -} - -function cmyk2hsl(args) { - return rgb2hsl(cmyk2rgb(args)); -} - -function cmyk2hsv(args) { - return rgb2hsv(cmyk2rgb(args)); -} - -function cmyk2hwb(args) { - return rgb2hwb(cmyk2rgb(args)); -} - -function cmyk2keyword(args) { - return rgb2keyword(cmyk2rgb(args)); -} - - -function xyz2rgb(xyz) { - var x = xyz[0] / 100, - y = xyz[1] / 100, - z = xyz[2] / 100, - r, g, b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r = (r * 12.92); - - g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g = (g * 12.92); - - b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b = (b * 12.92); - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -} - -function xyz2lab(xyz) { - var x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function xyz2lch(args) { - return lab2lch(xyz2lab(args)); -} - -function lab2xyz(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - x, y, z, y2; - - if (l <= 8) { - y = (l * 100) / 903.3; - y2 = (7.787 * (y / 100)) + (16 / 116); - } else { - y = 100 * Math.pow((l + 16) / 116, 3); - y2 = Math.pow(y / 100, 1/3); - } - - x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); - - z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); - - return [x, y, z]; -} - -function lab2lch(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - hr, h, c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - if (h < 0) { - h += 360; - } - c = Math.sqrt(a * a + b * b); - return [l, c, h]; -} - -function lab2rgb(args) { - return xyz2rgb(lab2xyz(args)); -} - -function lch2lab(lch) { - var l = lch[0], - c = lch[1], - h = lch[2], - a, b, hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - return [l, a, b]; -} - -function lch2xyz(args) { - return lab2xyz(lch2lab(args)); -} - -function lch2rgb(args) { - return lab2rgb(lch2lab(args)); -} - -function keyword2rgb(keyword) { - return cssKeywords[keyword]; -} - -function keyword2hsl(args) { - return rgb2hsl(keyword2rgb(args)); -} - -function keyword2hsv(args) { - return rgb2hsv(keyword2rgb(args)); -} - -function keyword2hwb(args) { - return rgb2hwb(keyword2rgb(args)); -} - -function keyword2cmyk(args) { - return rgb2cmyk(keyword2rgb(args)); -} - -function keyword2lab(args) { - return rgb2lab(keyword2rgb(args)); -} - -function keyword2xyz(args) { - return rgb2xyz(keyword2rgb(args)); -} - -var cssKeywords = { - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - 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], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - grey: [128,128,128], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - rebeccapurple: [102, 51, 153], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] -}; - -var reverseKeywords = {}; -for (var key in cssKeywords) { - reverseKeywords[JSON.stringify(cssKeywords[key])] = key; -} - -},{}],4:[function(require,module,exports){ -var conversions = require(3); - -var convert = function() { - return new Converter(); -} - -for (var func in conversions) { - // export Raw versions - convert[func + "Raw"] = (function(func) { - // accept array or plain args - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - return conversions[func](arg); - } - })(func); - - var pair = /(\w+)2(\w+)/.exec(func), - from = pair[1], - to = pair[2]; - - // export rgb2hsl and ["rgb"]["hsl"] - convert[from] = convert[from] || {}; - - convert[from][to] = convert[func] = (function(func) { - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - - var val = conversions[func](arg); - if (typeof val == "string" || val === undefined) - return val; // keyword - - for (var i = 0; i < val.length; i++) - val[i] = Math.round(val[i]); - return val; - } - })(func); -} - - -/* Converter does lazy conversion and caching */ -var Converter = function() { - this.convs = {}; -}; - -/* Either get the values for a space or - set the values for a space, depending on args */ -Converter.prototype.routeSpace = function(space, args) { - var values = args[0]; - if (values === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof values == "number") { - values = Array.prototype.slice.call(args); - } - - return this.setValues(space, values); -}; - -/* Set the values for a space, invalidating cache */ -Converter.prototype.setValues = function(space, values) { - this.space = space; - this.convs = {}; - this.convs[space] = values; - return this; -}; - -/* Get the values for a space. If there's already - a conversion for the space, fetch it, otherwise - compute it */ -Converter.prototype.getValues = function(space) { - var vals = this.convs[space]; - if (!vals) { - var fspace = this.space, - from = this.convs[fspace]; - vals = convert[fspace][space](from); - - this.convs[space] = vals; - } - return vals; -}; - -["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) { - Converter.prototype[space] = function(vals) { - return this.routeSpace(space, arguments); - } -}); - -module.exports = convert; -},{"3":3}],5:[function(require,module,exports){ -'use strict' - -module.exports = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "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], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -},{}],6:[function(require,module,exports){ -//! moment.js - -;(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - global.moment = factory() -}(this, (function () { 'use strict'; - - var hookCallback; - - function hooks () { - return hookCallback.apply(null, arguments); - } - - // This is done to register the method called with moment() - // without creating circular dependencies. - function setHookCallback (callback) { - hookCallback = callback; - } - - function isArray(input) { - return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; - } - - function isObject(input) { - // IE8 will treat undefined and null as object if it wasn't for - // input != null - return input != null && Object.prototype.toString.call(input) === '[object Object]'; - } - - function isObjectEmpty(obj) { - if (Object.getOwnPropertyNames) { - return (Object.getOwnPropertyNames(obj).length === 0); - } else { - var k; - for (k in obj) { - if (obj.hasOwnProperty(k)) { - return false; - } - } - return true; - } - } - - function isUndefined(input) { - return input === void 0; - } - - function isNumber(input) { - return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; - } - - function isDate(input) { - return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; - } - - function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } - - function hasOwnProp(a, b) { - return Object.prototype.hasOwnProperty.call(a, b); - } - - function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } - } - - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; - } - - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } - - return a; - } - - function createUTC (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, true).utc(); - } - - function defaultParsingFlags() { - // We need to deep clone this object. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso : false, - parsedDateParts : [], - meridiem : null, - rfc2822 : false, - weekdayMismatch : false - }; - } - - function getParsingFlags(m) { - if (m._pf == null) { - m._pf = defaultParsingFlags(); - } - return m._pf; - } - - var some; - if (Array.prototype.some) { - some = Array.prototype.some; - } else { - some = function (fun) { - var t = Object(this); - var len = t.length >>> 0; - - for (var i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } - - return false; - }; - } - - function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m); - var parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }); - var isNowValid = !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); - - if (m._strict) { - isNowValid = isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } - - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } - else { - return isNowValid; - } - } - return m._isValid; - } - - function createInvalid (flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } - else { - getParsingFlags(m).userInvalidated = true; - } - - return m; - } - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - var momentProperties = hooks.momentProperties = []; - - function copyConfig(to, from) { - var i, prop, val; - - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } - - return to; - } - - var updateInProgress = false; - - // Moment prototype object - function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); - } - // Prevent infinite loop in case updateOffset creates new moment - // objects. - if (updateInProgress === false) { - updateInProgress = true; - hooks.updateOffset(this); - updateInProgress = false; - } - } - - function isMoment (obj) { - return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); - } - - function absFloor (number) { - if (number < 0) { - // -0 -> 0 - return Math.ceil(number) || 0; - } else { - return Math.floor(number); - } - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - value = absFloor(coercedNumber); - } - - return value; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; - } - - function warn(msg) { - if (hooks.suppressDeprecationWarnings === false && - (typeof console !== 'undefined') && console.warn) { - console.warn('Deprecation warning: ' + msg); - } - } - - function deprecate(msg, fn) { - var firstTime = true; - - return extend(function () { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(null, msg); - } - if (firstTime) { - var args = []; - var arg; - for (var i = 0; i < arguments.length; i++) { - arg = ''; - if (typeof arguments[i] === 'object') { - arg += '\n[' + i + '] '; - for (var key in arguments[0]) { - arg += key + ': ' + arguments[0][key] + ', '; - } - arg = arg.slice(0, -2); // Remove trailing comma and space - } else { - arg = arguments[i]; - } - args.push(arg); - } - warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - var deprecations = {}; - - function deprecateSimple(name, msg) { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(name, msg); - } - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } - } - - hooks.suppressDeprecationWarnings = false; - hooks.deprecationHandler = null; - - function isFunction(input) { - return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; - } - - function set (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (isFunction(prop)) { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - this._config = config; - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. - // TODO: Remove "ordinalParse" fallback in next major release. - this._dayOfMonthOrdinalParseLenient = new RegExp( - (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + - '|' + (/\d{1,2}/).source); - } - - function mergeConfigs(parentConfig, childConfig) { - var res = extend({}, parentConfig), prop; - for (prop in childConfig) { - if (hasOwnProp(childConfig, prop)) { - if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { - res[prop] = {}; - extend(res[prop], parentConfig[prop]); - extend(res[prop], childConfig[prop]); - } else if (childConfig[prop] != null) { - res[prop] = childConfig[prop]; - } else { - delete res[prop]; - } - } - } - for (prop in parentConfig) { - if (hasOwnProp(parentConfig, prop) && - !hasOwnProp(childConfig, prop) && - isObject(parentConfig[prop])) { - // make sure changes to properties don't modify parent config - res[prop] = extend({}, res[prop]); - } - } - return res; - } - - function Locale(config) { - if (config != null) { - this.set(config); - } - } - - var keys; - - if (Object.keys) { - keys = Object.keys; - } else { - keys = function (obj) { - var i, res = []; - for (i in obj) { - if (hasOwnProp(obj, i)) { - res.push(i); - } - } - return res; - }; - } - - var defaultCalendar = { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }; - - function calendar (key, mom, now) { - var output = this._calendar[key] || this._calendar['sameElse']; - return isFunction(output) ? output.call(mom, now) : output; - } - - var defaultLongDateFormat = { - LTS : 'h:mm:ss A', - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }; - - function longDateFormat (key) { - var format = this._longDateFormat[key], - formatUpper = this._longDateFormat[key.toUpperCase()]; - - if (format || !formatUpper) { - return format; - } - - this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - - return this._longDateFormat[key]; - } - - var defaultInvalidDate = 'Invalid date'; - - function invalidDate () { - return this._invalidDate; - } - - var defaultOrdinal = '%d'; - var defaultDayOfMonthOrdinalParse = /\d{1,2}/; - - function ordinal (number) { - return this._ordinal.replace('%d', number); - } - - var defaultRelativeTime = { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d 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' - }; - - function relativeTime (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (isFunction(output)) ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - } - - function pastFuture (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return isFunction(format) ? format(output) : format.replace(/%s/i, output); - } - - var aliases = {}; - - function addUnitAlias (unit, shorthand) { - var lowerCase = unit.toLowerCase(); - aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; - } - - function normalizeUnits(units) { - return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; - } - - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - var priorities = {}; - - function addUnitPriority(unit, priority) { - priorities[unit] = priority; - } - - function getPrioritizedUnits(unitsObj) { - var units = []; - for (var u in unitsObj) { - units.push({unit: u, priority: priorities[u]}); - } - units.sort(function (a, b) { - return a.priority - b.priority; - }); - return units; - } - - function zeroFill(number, targetLength, forceSign) { - var absNumber = '' + Math.abs(number), - zerosToFill = targetLength - absNumber.length, - sign = number >= 0; - return (sign ? (forceSign ? '+' : '') : '-') + - Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; - } - - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; - - var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; - - var formatFunctions = {}; - - var formatTokenFunctions = {}; - - // token: 'M' - // padded: ['MM', 2] - // ordinal: 'Mo' - // callback: function () { this.month() + 1 } - function addFormatToken (token, padded, ordinal, callback) { - var func = callback; - if (typeof callback === 'string') { - func = function () { - return this[callback](); - }; - } - if (token) { - formatTokenFunctions[token] = func; - } - if (padded) { - formatTokenFunctions[padded[0]] = function () { - return zeroFill(func.apply(this, arguments), padded[1], padded[2]); - }; - } - if (ordinal) { - formatTokenFunctions[ordinal] = function () { - return this.localeData().ordinal(func.apply(this, arguments), token); - }; - } - } - - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); - } - return input.replace(/\\/g, ''); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = '', i; - for (i = 0; i < length; i++) { - output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } - - format = expandFormat(format, m.localeData()); - formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); - - return formatFunctions[format](m); - } - - function expandFormat(format, locale) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } - - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - var match1 = /\d/; // 0 - 9 - var match2 = /\d\d/; // 00 - 99 - var match3 = /\d{3}/; // 000 - 999 - var match4 = /\d{4}/; // 0000 - 9999 - var match6 = /[+-]?\d{6}/; // -999999 - 999999 - var match1to2 = /\d\d?/; // 0 - 99 - var match3to4 = /\d\d\d\d?/; // 999 - 9999 - var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 - var match1to3 = /\d{1,3}/; // 0 - 999 - var match1to4 = /\d{1,4}/; // 0 - 9999 - var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - - var matchUnsigned = /\d+/; // 0 - inf - var matchSigned = /[+-]?\d+/; // -inf - inf - - var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z - var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z - - var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 - - // any word (or two) characters or numbers including two/three word month in arabic. - // includes scottish gaelic two word and hyphenated months - var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; - - var regexes = {}; - - function addRegexToken (token, regex, strictRegex) { - regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { - return (isStrict && strictRegex) ? strictRegex : regex; - }; - } - - function getParseRegexForToken (token, config) { - if (!hasOwnProp(regexes, token)) { - return new RegExp(unescapeFormat(token)); - } - - return regexes[token](config._strict, config._locale); - } - - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function unescapeFormat(s) { - return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - })); - } - - function regexEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } - - var tokens = {}; - - function addParseToken (token, callback) { - var i, func = callback; - if (typeof token === 'string') { - token = [token]; - } - if (isNumber(callback)) { - func = function (input, array) { - array[callback] = toInt(input); - }; - } - for (i = 0; i < token.length; i++) { - tokens[token[i]] = func; - } - } - - function addWeekParseToken (token, callback) { - addParseToken(token, function (input, array, config, token) { - config._w = config._w || {}; - callback(input, config._w, config, token); - }); - } - - function addTimeToArrayFromToken(token, input, config) { - if (input != null && hasOwnProp(tokens, token)) { - tokens[token](input, config._a, config, token); - } - } - - var YEAR = 0; - var MONTH = 1; - var DATE = 2; - var HOUR = 3; - var MINUTE = 4; - var SECOND = 5; - var MILLISECOND = 6; - var WEEK = 7; - var WEEKDAY = 8; - - // FORMATTING - - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; - }); - - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); - - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); - - // ALIASES - - addUnitAlias('year', 'y'); - - // PRIORITIES - - addUnitPriority('year', 1); - - // PARSING - - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); - - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); - - // HELPERS - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - // HOOKS - - hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - // MOMENTS - - var getSetYear = makeGetSet('FullYear', true); - - function getIsLeapYear () { - return isLeapYear(this.year()); - } - - function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; - } - - function get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; - } - - function set$1 (mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); - } - else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - } - - // MOMENTS - - function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; - } - - - function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } - - function mod(n, x) { - return ((n % x) + x) % x; - } - - var indexOf; - - if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; - } else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } - } - return -1; - }; - } - - function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; - } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); - } - - // FORMATTING - - addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; - }); - - addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); - }); - - addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); - }); - - // ALIASES - - addUnitAlias('month', 'M'); - - // PRIORITY - - addUnitPriority('month', 8); - - // PARSING - - addRegexToken('M', match1to2); - addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); - }); - addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); - }); - - addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; - }); - - addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } - }); - - // LOCALES - - var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); - function localeMonths (m, format) { - if (!m) { - return isArray(this._months) ? this._months : - this._months['standalone']; - } - return isArray(this._months) ? this._months[m.month()] : - this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; - } - - var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); - function localeMonthsShort (m, format) { - if (!m) { - return isArray(this._monthsShort) ? this._monthsShort : - this._monthsShort['standalone']; - } - return isArray(this._monthsShort) ? this._monthsShort[m.month()] : - this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; - } - - function handleStrictParse(monthName, format, strict) { - var i, ii, mom, llc = monthName.toLocaleLowerCase(); - if (!this._monthsParse) { - // this is not used - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - for (i = 0; i < 12; ++i) { - mom = createUTC([2000, i]); - this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); - this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeMonthsParse (monthName, format, strict) { - var i, mom, regex; - - if (this._monthsParseExact) { - return handleStrictParse.call(this, monthName, format, strict); - } - - if (!this._monthsParse) { - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - } - - // TODO: add sorting - // Sorting makes sure if one month (or abbr) is a prefix of another - // see sorting in computeMonthsParse - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { - return i; - } - } - } - - // MOMENTS - - function setMonth (mom, value) { - var dayOfMonth; - - if (!mom.isValid()) { - // No op - return mom; - } - - if (typeof value === 'string') { - if (/^\d+$/.test(value)) { - value = toInt(value); - } else { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (!isNumber(value)) { - return mom; - } - } - } - - dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function getSetMonth (value) { - if (value != null) { - setMonth(this, value); - hooks.updateOffset(this, true); - return this; - } else { - return get(this, 'Month'); - } - } - - function getDaysInMonth () { - return daysInMonth(this.year(), this.month()); - } - - var defaultMonthsShortRegex = matchWord; - function monthsShortRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsShortStrictRegex; - } else { - return this._monthsShortRegex; - } - } else { - if (!hasOwnProp(this, '_monthsShortRegex')) { - this._monthsShortRegex = defaultMonthsShortRegex; - } - return this._monthsShortStrictRegex && isStrict ? - this._monthsShortStrictRegex : this._monthsShortRegex; - } - } - - var defaultMonthsRegex = matchWord; - function monthsRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsStrictRegex; - } else { - return this._monthsRegex; - } - } else { - if (!hasOwnProp(this, '_monthsRegex')) { - this._monthsRegex = defaultMonthsRegex; - } - return this._monthsStrictRegex && isStrict ? - this._monthsStrictRegex : this._monthsRegex; - } - } - - function computeMonthsParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var shortPieces = [], longPieces = [], mixedPieces = [], - i, mom; - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - shortPieces.push(this.monthsShort(mom, '')); - longPieces.push(this.months(mom, '')); - mixedPieces.push(this.months(mom, '')); - mixedPieces.push(this.monthsShort(mom, '')); - } - // Sorting makes sure if one month (or abbr) is a prefix of another it - // will match the longer piece. - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 12; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - } - for (i = 0; i < 24; i++) { - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._monthsShortRegex = this._monthsRegex; - this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - } - - function createDate (y, m, d, h, M, s, ms) { - // can't just apply() to create a date: - // https://stackoverflow.com/q/181348 - var date = new Date(y, m, d, h, M, s, ms); - - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { - date.setFullYear(y); - } - return date; - } - - function createUTCDate (y) { - var date = new Date(Date.UTC.apply(null, arguments)); - - // the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); - } - return date; - } - - // start-of-first-week - start-of-year - function firstWeekOffset(year, dow, doy) { - var // first-week day -- which january is always in the first week (4 for iso, 1 for other) - fwd = 7 + dow - doy, - // first-week day local weekday -- which local weekday is fwd - fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; - - return -fwdlw + fwd - 1; - } - - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, dow, doy) { - var localWeekday = (7 + weekday - dow) % 7, - weekOffset = firstWeekOffset(year, dow, doy), - dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, - resYear, resDayOfYear; - - if (dayOfYear <= 0) { - resYear = year - 1; - resDayOfYear = daysInYear(resYear) + dayOfYear; - } else if (dayOfYear > daysInYear(year)) { - resYear = year + 1; - resDayOfYear = dayOfYear - daysInYear(year); - } else { - resYear = year; - resDayOfYear = dayOfYear; - } - - return { - year: resYear, - dayOfYear: resDayOfYear - }; - } - - function weekOfYear(mom, dow, doy) { - var weekOffset = firstWeekOffset(mom.year(), dow, doy), - week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, - resWeek, resYear; - - if (week < 1) { - resYear = mom.year() - 1; - resWeek = week + weeksInYear(resYear, dow, doy); - } else if (week > weeksInYear(mom.year(), dow, doy)) { - resWeek = week - weeksInYear(mom.year(), dow, doy); - resYear = mom.year() + 1; - } else { - resYear = mom.year(); - resWeek = week; - } - - return { - week: resWeek, - year: resYear - }; - } - - function weeksInYear(year, dow, doy) { - var weekOffset = firstWeekOffset(year, dow, doy), - weekOffsetNext = firstWeekOffset(year + 1, dow, doy); - return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; - } - - // FORMATTING - - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); - - // ALIASES - - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); - - // PRIORITIES - - addUnitPriority('week', 5); - addUnitPriority('isoWeek', 5); - - // PARSING - - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); - - addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - }); - - // HELPERS - - // LOCALES - - function localeWeek (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } - - var defaultLocaleWeek = { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - }; - - function localeFirstDayOfWeek () { - return this._week.dow; - } - - function localeFirstDayOfYear () { - return this._week.doy; - } - - // MOMENTS - - function getSetWeek (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - function getSetISOWeek (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - // FORMATTING - - addFormatToken('d', 0, 'do', 'day'); - - addFormatToken('dd', 0, 0, function (format) { - return this.localeData().weekdaysMin(this, format); - }); - - addFormatToken('ddd', 0, 0, function (format) { - return this.localeData().weekdaysShort(this, format); - }); - - addFormatToken('dddd', 0, 0, function (format) { - return this.localeData().weekdays(this, format); - }); - - addFormatToken('e', 0, 0, 'weekday'); - addFormatToken('E', 0, 0, 'isoWeekday'); - - // ALIASES - - addUnitAlias('day', 'd'); - addUnitAlias('weekday', 'e'); - addUnitAlias('isoWeekday', 'E'); - - // PRIORITY - addUnitPriority('day', 11); - addUnitPriority('weekday', 11); - addUnitPriority('isoWeekday', 11); - - // PARSING - - addRegexToken('d', match1to2); - addRegexToken('e', match1to2); - addRegexToken('E', match1to2); - addRegexToken('dd', function (isStrict, locale) { - return locale.weekdaysMinRegex(isStrict); - }); - addRegexToken('ddd', function (isStrict, locale) { - return locale.weekdaysShortRegex(isStrict); - }); - addRegexToken('dddd', function (isStrict, locale) { - return locale.weekdaysRegex(isStrict); - }); - - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { - var weekday = config._locale.weekdaysParse(input, token, config._strict); - // if we didn't get a weekday name, mark the date as invalid - if (weekday != null) { - week.d = weekday; - } else { - getParsingFlags(config).invalidWeekday = input; - } - }); - - addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { - week[token] = toInt(input); - }); - - // HELPERS - - function parseWeekday(input, locale) { - if (typeof input !== 'string') { - return input; - } - - if (!isNaN(input)) { - return parseInt(input, 10); - } - - input = locale.weekdaysParse(input); - if (typeof input === 'number') { - return input; - } - - return null; - } - - function parseIsoWeekday(input, locale) { - if (typeof input === 'string') { - return locale.weekdaysParse(input) % 7 || 7; - } - return isNaN(input) ? null : input; - } - - // LOCALES - - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); - function localeWeekdays (m, format) { - if (!m) { - return isArray(this._weekdays) ? this._weekdays : - this._weekdays['standalone']; - } - return isArray(this._weekdays) ? this._weekdays[m.day()] : - this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; - } - - var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); - function localeWeekdaysShort (m) { - return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; - } - - var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); - function localeWeekdaysMin (m) { - return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; - } - - function handleStrictParse$1(weekdayName, format, strict) { - var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._shortWeekdaysParse = []; - this._minWeekdaysParse = []; - - for (i = 0; i < 7; ++i) { - mom = createUTC([2000, 1]).day(i); - this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); - this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); - this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeWeekdaysParse (weekdayName, format, strict) { - var i, mom, regex; - - if (this._weekdaysParseExact) { - return handleStrictParse$1.call(this, weekdayName, format, strict); - } - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._minWeekdaysParse = []; - this._shortWeekdaysParse = []; - this._fullWeekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - - mom = createUTC([2000, 1]).day(i); - if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); - } - if (!this._weekdaysParse[i]) { - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - } - - // MOMENTS - - function getSetDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - } - - function getSetLocaleDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - } - - function getSetISODayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - - if (input != null) { - var weekday = parseIsoWeekday(input, this.localeData()); - return this.day(this.day() % 7 ? weekday : weekday - 7); - } else { - return this.day() || 7; - } - } - - var defaultWeekdaysRegex = matchWord; - function weekdaysRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysStrictRegex; - } else { - return this._weekdaysRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysRegex')) { - this._weekdaysRegex = defaultWeekdaysRegex; - } - return this._weekdaysStrictRegex && isStrict ? - this._weekdaysStrictRegex : this._weekdaysRegex; - } - } - - var defaultWeekdaysShortRegex = matchWord; - function weekdaysShortRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysShortStrictRegex; - } else { - return this._weekdaysShortRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysShortRegex')) { - this._weekdaysShortRegex = defaultWeekdaysShortRegex; - } - return this._weekdaysShortStrictRegex && isStrict ? - this._weekdaysShortStrictRegex : this._weekdaysShortRegex; - } - } - - var defaultWeekdaysMinRegex = matchWord; - function weekdaysMinRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysMinStrictRegex; - } else { - return this._weekdaysMinRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysMinRegex')) { - this._weekdaysMinRegex = defaultWeekdaysMinRegex; - } - return this._weekdaysMinStrictRegex && isStrict ? - this._weekdaysMinStrictRegex : this._weekdaysMinRegex; - } - } - - - function computeWeekdaysParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], - i, mom, minp, shortp, longp; - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, 1]).day(i); - minp = this.weekdaysMin(mom, ''); - shortp = this.weekdaysShort(mom, ''); - longp = this.weekdays(mom, ''); - minPieces.push(minp); - shortPieces.push(shortp); - longPieces.push(longp); - mixedPieces.push(minp); - mixedPieces.push(shortp); - mixedPieces.push(longp); - } - // Sorting makes sure if one weekday (or abbr) is a prefix of another it - // will match the longer piece. - minPieces.sort(cmpLenRev); - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 7; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._weekdaysShortRegex = this._weekdaysRegex; - this._weekdaysMinRegex = this._weekdaysRegex; - - this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); - } - - // FORMATTING - - function hFormat() { - return this.hours() % 12 || 12; - } - - function kFormat() { - return this.hours() || 24; - } - - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, hFormat); - addFormatToken('k', ['kk', 2], 0, kFormat); - - addFormatToken('hmm', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); - }); - - addFormatToken('hmmss', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - addFormatToken('Hmm', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2); - }); - - addFormatToken('Hmmss', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - function meridiem (token, lowercase) { - addFormatToken(token, 0, 0, function () { - return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); - }); - } - - meridiem('a', true); - meridiem('A', false); - - // ALIASES - - addUnitAlias('hour', 'h'); - - // PRIORITY - addUnitPriority('hour', 13); - - // PARSING - - function matchMeridiem (isStrict, locale) { - return locale._meridiemParse; - } - - addRegexToken('a', matchMeridiem); - addRegexToken('A', matchMeridiem); - addRegexToken('H', match1to2); - addRegexToken('h', match1to2); - addRegexToken('k', match1to2); - addRegexToken('HH', match1to2, match2); - addRegexToken('hh', match1to2, match2); - addRegexToken('kk', match1to2, match2); - - addRegexToken('hmm', match3to4); - addRegexToken('hmmss', match5to6); - addRegexToken('Hmm', match3to4); - addRegexToken('Hmmss', match5to6); - - addParseToken(['H', 'HH'], HOUR); - addParseToken(['k', 'kk'], function (input, array, config) { - var kInput = toInt(input); - array[HOUR] = kInput === 24 ? 0 : kInput; - }); - addParseToken(['a', 'A'], function (input, array, config) { - config._isPm = config._locale.isPM(input); - config._meridiem = input; - }); - addParseToken(['h', 'hh'], function (input, array, config) { - array[HOUR] = toInt(input); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('Hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - }); - addParseToken('Hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - }); - - // LOCALES - - function localeIsPM (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - } - - var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; - function localeMeridiem (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - } - - - // MOMENTS - - // Setting the hour should keep the time, because the user explicitly - // specified which hour they want. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - var getSetHour = makeGetSet('Hours', true); - - var baseConfig = { - calendar: defaultCalendar, - longDateFormat: defaultLongDateFormat, - invalidDate: defaultInvalidDate, - ordinal: defaultOrdinal, - dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, - relativeTime: defaultRelativeTime, - - months: defaultLocaleMonths, - monthsShort: defaultLocaleMonthsShort, - - week: defaultLocaleWeek, - - weekdays: defaultLocaleWeekdays, - weekdaysMin: defaultLocaleWeekdaysMin, - weekdaysShort: defaultLocaleWeekdaysShort, - - meridiemParse: defaultLocaleMeridiemParse - }; - - // internal storage for locale config files - var locales = {}; - var localeFamilies = {}; - var globalLocale; - - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return globalLocale; - } - - function loadLocale(name) { - var oldLocale = null; - // TODO: Find a better way to register and load all the locales in Node - if (!locales[name] && (typeof module !== 'undefined') && - module && module.exports) { - try { - oldLocale = globalLocale._abbr; - var aliasedRequire = require; - aliasedRequire('./locale/' + name); - getSetGlobalLocale(oldLocale); - } catch (e) {} - } - return locales[name]; - } - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - function getSetGlobalLocale (key, values) { - var data; - if (key) { - if (isUndefined(values)) { - data = getLocale(key); - } - else { - data = defineLocale(key, values); - } - - if (data) { - // moment.duration._locale = moment._locale = data; - globalLocale = data; - } - else { - if ((typeof console !== 'undefined') && console.warn) { - //warn user if arguments are passed but the locale could not be set - console.warn('Locale ' + key + ' not found. Did you forget to load it?'); - } - } - } - - return globalLocale._abbr; - } - - function defineLocale (name, config) { - if (config !== null) { - var locale, parentConfig = baseConfig; - config.abbr = name; - if (locales[name] != null) { - deprecateSimple('defineLocaleOverride', - 'use moment.updateLocale(localeName, config) to change ' + - 'an existing locale. moment.defineLocale(localeName, ' + - 'config) should only be used for creating a new locale ' + - 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); - parentConfig = locales[name]._config; - } else if (config.parentLocale != null) { - if (locales[config.parentLocale] != null) { - parentConfig = locales[config.parentLocale]._config; - } else { - locale = loadLocale(config.parentLocale); - if (locale != null) { - parentConfig = locale._config; - } else { - if (!localeFamilies[config.parentLocale]) { - localeFamilies[config.parentLocale] = []; - } - localeFamilies[config.parentLocale].push({ - name: name, - config: config - }); - return null; - } - } - } - locales[name] = new Locale(mergeConfigs(parentConfig, config)); - - if (localeFamilies[name]) { - localeFamilies[name].forEach(function (x) { - defineLocale(x.name, x.config); - }); - } - - // backwards compat for now: also set the locale - // make sure we set the locale AFTER all child locales have been - // created, so we won't end up with the child locale set. - getSetGlobalLocale(name); - - - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - } - - function updateLocale(name, config) { - if (config != null) { - var locale, tmpLocale, parentConfig = baseConfig; - // MERGE - tmpLocale = loadLocale(name); - if (tmpLocale != null) { - parentConfig = tmpLocale._config; - } - config = mergeConfigs(parentConfig, config); - locale = new Locale(config); - locale.parentLocale = locales[name]; - locales[name] = locale; - - // backwards compat for now: also set the locale - getSetGlobalLocale(name); - } else { - // pass null for config to unupdate, useful for tests - if (locales[name] != null) { - if (locales[name].parentLocale != null) { - locales[name] = locales[name].parentLocale; - } else if (locales[name] != null) { - delete locales[name]; - } - } - } - return locales[name]; - } - - // returns locale data - function getLocale (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - - if (!key) { - return globalLocale; - } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } - - return chooseLocale(key); - } - - function listLocales() { - return keys(locales); - } - - function checkOverflow (m) { - var overflow; - var a = m._a; - - if (a && getParsingFlags(m).overflow === -2) { - overflow = - a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : - a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : - a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : - a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : - a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : - a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - if (getParsingFlags(m)._overflowWeeks && overflow === -1) { - overflow = WEEK; - } - if (getParsingFlags(m)._overflowWeekday && overflow === -1) { - overflow = WEEKDAY; - } - - getParsingFlags(m).overflow = overflow; - } - - return m; - } - - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; - } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray (config) { - var i, date, input = [], currentDate, expectedWeekday, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); - - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } - - if (config._nextDay) { - config._a[HOUR] = 24; - } - - // check for mismatching day of week - if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { - getParsingFlags(config).weekdayMismatch = true; - } - } - - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - var curWeek = weekOfYear(createLocal(), dow, doy); - - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); - - // Default to current week. - week = defaults(w.w, curWeek.week); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from begining of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to begining of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - } - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - - var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; - - var isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], - ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], - ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], - ['GGGG-[W]WW', /\d{4}-W\d\d/, false], - ['YYYY-DDD', /\d{4}-\d{3}/], - ['YYYY-MM', /\d{4}-\d\d/, false], - ['YYYYYYMMDD', /[+-]\d{10}/], - ['YYYYMMDD', /\d{8}/], - // YYYYMM is NOT allowed by the standard - ['GGGG[W]WWE', /\d{4}W\d{3}/], - ['GGGG[W]WW', /\d{4}W\d{2}/, false], - ['YYYYDDD', /\d{7}/] - ]; - - // iso time formats and regexes - var isoTimes = [ - ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], - ['HH:mm:ss', /\d\d:\d\d:\d\d/], - ['HH:mm', /\d\d:\d\d/], - ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], - ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], - ['HHmmss', /\d\d\d\d\d\d/], - ['HHmm', /\d\d\d\d/], - ['HH', /\d\d/] - ]; - - var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; - - // date from iso format - function configFromISO(config) { - var i, l, - string = config._i, - match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), - allowTime, dateFormat, timeFormat, tzFormat; - - if (match) { - getParsingFlags(config).iso = true; - - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(match[1])) { - dateFormat = isoDates[i][0]; - allowTime = isoDates[i][2] !== false; - break; - } - } - if (dateFormat == null) { - config._isValid = false; - return; - } - if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(match[3])) { - // match[2] should be 'T' or space - timeFormat = (match[2] || ' ') + isoTimes[i][0]; - break; - } - } - if (timeFormat == null) { - config._isValid = false; - return; - } - } - if (!allowTime && timeFormat != null) { - config._isValid = false; - return; - } - if (match[4]) { - if (tzRegex.exec(match[4])) { - tzFormat = 'Z'; - } else { - config._isValid = false; - return; - } - } - config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); - configFromStringAndFormat(config); - } else { - config._isValid = false; - } - } - - // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; - - function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10) - ]; - - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } - - return result; - } - - function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; - } - - function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - } - - function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } - } - return true; - } - - var obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60 - }; - - function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10); - var m = hm % 100, h = (hm - m) / 100; - return h * 60 + m; - } - } - - // date and time from ref 2822 format - function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)); - if (match) { - var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } - - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); - - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - - getParsingFlags(config).rfc2822 = true; - } else { - config._isValid = false; - } - } - - // date from iso format or fallback - function configFromString(config) { - var matched = aspNetJsonRegex.exec(config._i); - - if (matched !== null) { - config._d = new Date(+matched[1]); - return; - } - - configFromISO(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - configFromRFC2822(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - // Final attempt, use Input Fallback - hooks.createFromInputFallback(config); - } - - hooks.createFromInputFallback = deprecate( - 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + - 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + - 'discouraged and will be removed in an upcoming major release. Please refer to ' + - 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', - function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); - } - ); - - // constant that refers to the ISO standard - hooks.ISO_8601 = function () {}; - - // constant that refers to the RFC 2822 form - hooks.RFC_2822 = function () {}; - - // date from string and format string - function configFromStringAndFormat(config) { - // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === hooks.ISO_8601) { - configFromISO(config); - return; - } - if (config._f === hooks.RFC_2822) { - configFromRFC2822(config); - return; - } - config._a = []; - getParsingFlags(config).empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; - - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - // console.log('token', token, 'parsedInput', parsedInput, - // 'regex', getParseRegexForToken(token, config)); - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - getParsingFlags(config).unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - getParsingFlags(config).empty = false; - } - else { - getParsingFlags(config).unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - getParsingFlags(config).unusedTokens.push(token); - } - } - - // add remaining unparsed input length to the string - getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - getParsingFlags(config).unusedInput.push(string); - } - - // clear _12h flag if hour is <= 12 - if (config._a[HOUR] <= 12 && - getParsingFlags(config).bigHour === true && - config._a[HOUR] > 0) { - getParsingFlags(config).bigHour = undefined; - } - - getParsingFlags(config).parsedDateParts = config._a.slice(0); - getParsingFlags(config).meridiem = config._meridiem; - // handle meridiem - config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); - - configFromArray(config); - checkOverflow(config); - } - - - function meridiemFixWrap (locale, hour, meridiem) { - var isPm; - - if (meridiem == null) { - // nothing to do - return hour; - } - if (locale.meridiemHour != null) { - return locale.meridiemHour(hour, meridiem); - } else if (locale.isPM != null) { - // Fallback - isPm = locale.isPM(meridiem); - if (isPm && hour < 12) { - hour += 12; - } - if (!isPm && hour === 12) { - hour = 0; - } - return hour; - } else { - // this is not supposed to happen - return hour; - } - } - - // date from string and array of format strings - function configFromStringAndArray(config) { - var tempConfig, - bestMoment, - - scoreToBeat, - i, - currentScore; - - if (config._f.length === 0) { - getParsingFlags(config).invalidFormat = true; - config._d = new Date(NaN); - return; - } - - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._f = config._f[i]; - configFromStringAndFormat(tempConfig); - - if (!isValid(tempConfig)) { - continue; - } - - // if there is any input that was not parsed add a penalty for that format - currentScore += getParsingFlags(tempConfig).charsLeftOver; - - //or tokens - currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; - - getParsingFlags(tempConfig).score = currentScore; - - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - - extend(config, bestMoment || tempConfig); - } - - function configFromObject(config) { - if (config._d) { - return; - } - - var i = normalizeObjectUnits(config._i); - config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { - return obj && parseInt(obj, 10); - }); - - configFromArray(config); - } - - function createFromConfig (config) { - var res = new Moment(checkOverflow(prepareConfig(config))); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } - - return res; - } - - function prepareConfig (config) { - var input = config._i, - format = config._f; - - config._locale = config._locale || getLocale(config._l); - - if (input === null || (format === undefined && input === '')) { - return createInvalid({nullInput: true}); - } - - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } - - if (isMoment(input)) { - return new Moment(checkOverflow(input)); - } else if (isDate(input)) { - config._d = input; - } else if (isArray(format)) { - configFromStringAndArray(config); - } else if (format) { - configFromStringAndFormat(config); - } else { - configFromInput(config); - } - - if (!isValid(config)) { - config._d = null; - } - - return config; - } - - function configFromInput(config) { - var input = config._i; - if (isUndefined(input)) { - config._d = new Date(hooks.now()); - } else if (isDate(input)) { - config._d = new Date(input.valueOf()); - } else if (typeof input === 'string') { - configFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - configFromArray(config); - } else if (isObject(input)) { - configFromObject(config); - } else if (isNumber(input)) { - // from milliseconds - config._d = new Date(input); - } else { - hooks.createFromInputFallback(config); - } - } - - function createLocalOrUTC (input, format, locale, strict, isUTC) { - var c = {}; - - if (locale === true || locale === false) { - strict = locale; - locale = undefined; - } - - if ((isObject(input) && isObjectEmpty(input)) || - (isArray(input) && input.length === 0)) { - input = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c._isAMomentObject = true; - c._useUTC = c._isUTC = isUTC; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - - return createFromConfig(c); - } - - function createLocal (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, false); - } - - var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other < this ? this : other; - } else { - return createInvalid(); - } - } - ); - - var prototypeMax = deprecate( - 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other > this ? this : other; - } else { - return createInvalid(); - } - } - ); - - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return createLocal(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (!moments[i].isValid() || moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } - - // TODO: Use [].sort instead? - function min () { - var args = [].slice.call(arguments, 0); - - return pickBy('isBefore', args); - } - - function max () { - var args = [].slice.call(arguments, 0); - - return pickBy('isAfter', args); - } - - var now = function () { - return Date.now ? Date.now() : +(new Date()); - }; - - var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; - - function isDurationValid(m) { - for (var key in m) { - if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { - return false; - } - } - - var unitHasDecimal = false; - for (var i = 0; i < ordering.length; ++i) { - if (m[ordering[i]]) { - if (unitHasDecimal) { - return false; // only allow non-integers for smallest unit - } - if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { - unitHasDecimal = true; - } - } - } - - return true; - } - - function isValid$1() { - return this._isValid; - } - - function createInvalid$1() { - return createDuration(NaN); - } - - function Duration (duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - this._isValid = isDurationValid(normalizedInput); - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible to translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - - this._data = {}; - - this._locale = getLocale(); - - this._bubble(); - } - - function isDuration (obj) { - return obj instanceof Duration; - } - - function absRound (number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); - } - } - - // FORMATTING - - function offset (token, separator) { - addFormatToken(token, 0, 0, function () { - var offset = this.utcOffset(); - var sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); - }); - } - - offset('Z', ':'); - offset('ZZ', ''); - - // PARSING - - addRegexToken('Z', matchShortOffset); - addRegexToken('ZZ', matchShortOffset); - addParseToken(['Z', 'ZZ'], function (input, array, config) { - config._useUTC = true; - config._tzm = offsetFromString(matchShortOffset, input); - }); - - // HELPERS - - // timezone chunker - // '+10:00' > ['10', '00'] - // '-1530' > ['-15', '30'] - var chunkOffset = /([\+\-]|\d\d)/gi; - - function offsetFromString(matcher, string) { - var matches = (string || '').match(matcher); - - if (matches === null) { - return null; - } - - var chunk = matches[matches.length - 1] || []; - var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; - var minutes = +(parts[1] * 60) + toInt(parts[2]); - - return minutes === 0 ? - 0 : - parts[0] === '+' ? minutes : -minutes; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function cloneWithOffset(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); - // Use low-level api, because this fn is low-level api. - res._d.setTime(res._d.valueOf() + diff); - hooks.updateOffset(res, false); - return res; - } else { - return createLocal(input).local(); - } - } - - function getDateOffset (m) { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return -Math.round(m._d.getTimezoneOffset() / 15) * 15; - } - - // HOOKS - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - hooks.updateOffset = function () {}; - - // MOMENTS - - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - function getSetOffset (input, keepLocalTime, keepMinutes) { - var offset = this._offset || 0, - localAdjust; - if (!this.isValid()) { - return input != null ? this : NaN; - } - if (input != null) { - if (typeof input === 'string') { - input = offsetFromString(matchShortOffset, input); - if (input === null) { - return this; - } - } else if (Math.abs(input) < 16 && !keepMinutes) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = getDateOffset(this); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.add(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addSubtract(this, createDuration(input - offset, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - hooks.updateOffset(this, true); - this._changeInProgress = null; - } - } - return this; - } else { - return this._isUTC ? offset : getDateOffset(this); - } - } - - function getSetZone (input, keepLocalTime) { - if (input != null) { - if (typeof input !== 'string') { - input = -input; - } - - this.utcOffset(input, keepLocalTime); - - return this; - } else { - return -this.utcOffset(); - } - } - - function setOffsetToUTC (keepLocalTime) { - return this.utcOffset(0, keepLocalTime); - } - - function setOffsetToLocal (keepLocalTime) { - if (this._isUTC) { - this.utcOffset(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.subtract(getDateOffset(this), 'm'); - } - } - return this; - } - - function setOffsetToParsedOffset () { - if (this._tzm != null) { - this.utcOffset(this._tzm, false, true); - } else if (typeof this._i === 'string') { - var tZone = offsetFromString(matchOffset, this._i); - if (tZone != null) { - this.utcOffset(tZone); - } - else { - this.utcOffset(0, true); - } - } - return this; - } - - function hasAlignedHourOffset (input) { - if (!this.isValid()) { - return false; - } - input = input ? createLocal(input).utcOffset() : 0; - - return (this.utcOffset() - input) % 60 === 0; - } - - function isDaylightSavingTime () { - return ( - this.utcOffset() > this.clone().month(0).utcOffset() || - this.utcOffset() > this.clone().month(5).utcOffset() - ); - } - - function isDaylightSavingTimeShifted () { - if (!isUndefined(this._isDSTShifted)) { - return this._isDSTShifted; - } - - var c = {}; - - copyConfig(c, this); - c = prepareConfig(c); - - if (c._a) { - var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); - this._isDSTShifted = this.isValid() && - compareArrays(c._a, other.toArray()) > 0; - } else { - this._isDSTShifted = false; - } - - return this._isDSTShifted; - } - - function isLocal () { - return this.isValid() ? !this._isUTC : false; - } - - function isUtcOffset () { - return this.isValid() ? this._isUTC : false; - } - - function isUtc () { - return this.isValid() ? this._isUTC && this._offset === 0 : false; - } - - // ASP.NET json date format regex - var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; - - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - // and further modified to allow for strings containing both week and day - var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - - function createDuration (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - diffRes; - - if (isDuration(input)) { - duration = { - ms : input._milliseconds, - d : input._days, - M : input._months - }; - } else if (isNumber(input)) { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : 0, - d : toInt(match[DATE]) * sign, - h : toInt(match[HOUR]) * sign, - m : toInt(match[MINUTE]) * sign, - s : toInt(match[SECOND]) * sign, - ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match - }; - } else if (!!(match = isoRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; - duration = { - y : parseIso(match[2], sign), - M : parseIso(match[3], sign), - w : parseIso(match[4], sign), - d : parseIso(match[5], sign), - h : parseIso(match[6], sign), - m : parseIso(match[7], sign), - s : parseIso(match[8], sign) - }; - } else if (duration == null) {// checks for null or undefined - duration = {}; - } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); - - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } - - ret = new Duration(duration); - - if (isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; - } - - return ret; - } - - createDuration.fn = Duration.prototype; - createDuration.invalid = createInvalid$1; - - function parseIso (inp, sign) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - } - - function positiveMomentsDifference(base, other) { - var res = {milliseconds: 0, months: 0}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } - - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - if (!(base.isValid() && other.isValid())) { - return {milliseconds: 0, months: 0}; - } - - other = cloneWithOffset(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + - 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = createDuration(val, period); - addSubtract(this, dur, direction); - return this; - }; - } - - function addSubtract (mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = absRound(duration._days), - months = absRound(duration._months); - - if (!mom.isValid()) { - // No op - return; - } - - updateOffset = updateOffset == null ? true : updateOffset; - - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); - } - if (days) { - set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); - } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); - } - if (updateOffset) { - hooks.updateOffset(mom, days || months); - } - } - - var add = createAdder(1, 'add'); - var subtract = createAdder(-1, 'subtract'); - - function getCalendarFormat(myMoment, now) { - var diff = myMoment.diff(now, 'days', true); - return diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - } - - function calendar$1 (time, formats) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - format = hooks.calendarFormat(this, sod) || 'sameElse'; - - var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); - - return this.format(output || this.localeData().calendar(format, this, createLocal(now))); - } - - function clone () { - return new Moment(this); - } - - function isAfter (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); - if (units === 'millisecond') { - return this.valueOf() > localInput.valueOf(); - } else { - return localInput.valueOf() < this.clone().startOf(units).valueOf(); - } - } - - function isBefore (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); - if (units === 'millisecond') { - return this.valueOf() < localInput.valueOf(); - } else { - return this.clone().endOf(units).valueOf() < localInput.valueOf(); - } - } - - function isBetween (from, to, units, inclusivity) { - inclusivity = inclusivity || '()'; - return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && - (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); - } - - function isSame (input, units) { - var localInput = isMoment(input) ? input : createLocal(input), - inputMs; - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units || 'millisecond'); - if (units === 'millisecond') { - return this.valueOf() === localInput.valueOf(); - } else { - inputMs = localInput.valueOf(); - return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); - } - } - - function isSameOrAfter (input, units) { - return this.isSame(input, units) || this.isAfter(input,units); - } - - function isSameOrBefore (input, units) { - return this.isSame(input, units) || this.isBefore(input,units); - } - - function diff (input, units, asFloat) { - var that, - zoneDelta, - output; - - if (!this.isValid()) { - return NaN; - } - - that = cloneWithOffset(input, this); - - if (!that.isValid()) { - return NaN; - } - - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; - - units = normalizeUnits(units); - - switch (units) { - case 'year': output = monthDiff(this, that) / 12; break; - case 'month': output = monthDiff(this, that); break; - case 'quarter': output = monthDiff(this, that) / 3; break; - case 'second': output = (this - that) / 1e3; break; // 1000 - case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 - case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 - case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst - case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: output = this - that; - } - - return asFloat ? output : absFloor(output); - } - - function monthDiff (a, b) { - // difference in months - var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), - // b is in (anchor - 1 month, anchor + 1 month) - anchor = a.clone().add(wholeMonthDiff, 'months'), - anchor2, adjust; - - if (b - anchor < 0) { - anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor - anchor2); - } else { - anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor2 - anchor); - } - - //check for negative zero, return zero if negative zero - return -(wholeMonthDiff + adjust) || 0; - } - - hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; - - function toString () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - } - - function toISOString(keepOffset) { - if (!this.isValid()) { - return null; - } - var utc = keepOffset !== true; - var m = utc ? this.clone().utc() : this; - if (m.year() < 0 || m.year() > 9999) { - return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can - if (utc) { - return this.toDate().toISOString(); - } else { - return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); - } - } - return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - - /** - * Return a human readable representation of a moment that can - * also be evaluated to get a new moment which is the same - * - * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects - */ - function inspect () { - if (!this.isValid()) { - return 'moment.invalid(/* ' + this._i + ' */)'; - } - var func = 'moment'; - var zone = ''; - if (!this.isLocal()) { - func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; - zone = 'Z'; - } - var prefix = '[' + func + '("]'; - var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; - var datetime = '-MM-DD[T]HH:mm:ss.SSS'; - var suffix = zone + '[")]'; - - return this.format(prefix + year + datetime + suffix); - } - - function format (inputString) { - if (!inputString) { - inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; - } - var output = formatMoment(this, inputString); - return this.localeData().postformat(output); - } - - function from (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function fromNow (withoutSuffix) { - return this.from(createLocal(), withoutSuffix); - } - - function to (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function toNow (withoutSuffix) { - return this.to(createLocal(), withoutSuffix); - } - - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - function locale (key) { - var newLocaleData; - - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = getLocale(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - } - - var lang = deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ); - - function localeData () { - return this._locale; - } - - function startOf (units) { - units = normalizeUnits(units); - // the following switch intentionally omits break keywords - // to utilize falling through the cases. - switch (units) { - case 'year': - this.month(0); - /* falls through */ - case 'quarter': - case 'month': - this.date(1); - /* falls through */ - case 'week': - case 'isoWeek': - case 'day': - case 'date': - this.hours(0); - /* falls through */ - case 'hour': - this.minutes(0); - /* falls through */ - case 'minute': - this.seconds(0); - /* falls through */ - case 'second': - this.milliseconds(0); - } - - // weeks are a special case - if (units === 'week') { - this.weekday(0); - } - if (units === 'isoWeek') { - this.isoWeekday(1); - } - - // quarters are also special - if (units === 'quarter') { - this.month(Math.floor(this.month() / 3) * 3); - } - - return this; - } - - function endOf (units) { - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond') { - return this; - } - - // 'date' is an alias for 'day', so it should be considered as such. - if (units === 'date') { - units = 'day'; - } - - return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); - } - - function valueOf () { - return this._d.valueOf() - ((this._offset || 0) * 60000); - } - - function unix () { - return Math.floor(this.valueOf() / 1000); - } - - function toDate () { - return new Date(this.valueOf()); - } - - function toArray () { - var m = this; - return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; - } - - function toObject () { - var m = this; - return { - years: m.year(), - months: m.month(), - date: m.date(), - hours: m.hours(), - minutes: m.minutes(), - seconds: m.seconds(), - milliseconds: m.milliseconds() - }; - } - - function toJSON () { - // new Date(NaN).toJSON() === null - return this.isValid() ? this.toISOString() : null; - } - - function isValid$2 () { - return isValid(this); - } - - function parsingFlags () { - return extend({}, getParsingFlags(this)); - } - - function invalidAt () { - return getParsingFlags(this).overflow; - } - - function creationData() { - return { - input: this._i, - format: this._f, - locale: this._locale, - isUTC: this._isUTC, - strict: this._strict - }; - } - - // FORMATTING - - addFormatToken(0, ['gg', 2], 0, function () { - return this.weekYear() % 100; - }); - - addFormatToken(0, ['GG', 2], 0, function () { - return this.isoWeekYear() % 100; - }); - - function addWeekYearFormatToken (token, getter) { - addFormatToken(0, [token, token.length], 0, getter); - } - - addWeekYearFormatToken('gggg', 'weekYear'); - addWeekYearFormatToken('ggggg', 'weekYear'); - addWeekYearFormatToken('GGGG', 'isoWeekYear'); - addWeekYearFormatToken('GGGGG', 'isoWeekYear'); - - // ALIASES - - addUnitAlias('weekYear', 'gg'); - addUnitAlias('isoWeekYear', 'GG'); - - // PRIORITY - - addUnitPriority('weekYear', 1); - addUnitPriority('isoWeekYear', 1); - - - // PARSING - - addRegexToken('G', matchSigned); - addRegexToken('g', matchSigned); - addRegexToken('GG', match1to2, match2); - addRegexToken('gg', match1to2, match2); - addRegexToken('GGGG', match1to4, match4); - addRegexToken('gggg', match1to4, match4); - addRegexToken('GGGGG', match1to6, match6); - addRegexToken('ggggg', match1to6, match6); - - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { - week[token.substr(0, 2)] = toInt(input); - }); - - addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = hooks.parseTwoDigitYear(input); - }); - - // MOMENTS - - function getSetWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, - this.week(), - this.weekday(), - this.localeData()._week.dow, - this.localeData()._week.doy); - } - - function getSetISOWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, this.isoWeek(), this.isoWeekday(), 1, 4); - } - - function getISOWeeksInYear () { - return weeksInYear(this.year(), 1, 4); - } - - function getWeeksInYear () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - } - - function getSetWeekYearHelper(input, week, weekday, dow, doy) { - var weeksTarget; - if (input == null) { - return weekOfYear(this, dow, doy).year; - } else { - weeksTarget = weeksInYear(input, dow, doy); - if (week > weeksTarget) { - week = weeksTarget; - } - return setWeekAll.call(this, input, week, weekday, dow, doy); - } - } - - function setWeekAll(weekYear, week, weekday, dow, doy) { - var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), - date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); - - this.year(date.getUTCFullYear()); - this.month(date.getUTCMonth()); - this.date(date.getUTCDate()); - return this; - } - - // FORMATTING - - addFormatToken('Q', 0, 'Qo', 'quarter'); - - // ALIASES - - addUnitAlias('quarter', 'Q'); - - // PRIORITY - - addUnitPriority('quarter', 7); - - // PARSING - - addRegexToken('Q', match1); - addParseToken('Q', function (input, array) { - array[MONTH] = (toInt(input) - 1) * 3; - }); - - // MOMENTS - - function getSetQuarter (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - } - - // FORMATTING - - addFormatToken('D', ['DD', 2], 'Do', 'date'); - - // ALIASES - - addUnitAlias('date', 'D'); - - // PRIORITY - addUnitPriority('date', 9); - - // PARSING - - addRegexToken('D', match1to2); - addRegexToken('DD', match1to2, match2); - addRegexToken('Do', function (isStrict, locale) { - // TODO: Remove "ordinalParse" fallback in next major release. - return isStrict ? - (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : - locale._dayOfMonthOrdinalParseLenient; - }); - - addParseToken(['D', 'DD'], DATE); - addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0]); - }); - - // MOMENTS - - var getSetDayOfMonth = makeGetSet('Date', true); - - // FORMATTING - - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); - - // ALIASES - - addUnitAlias('dayOfYear', 'DDD'); - - // PRIORITY - addUnitPriority('dayOfYear', 4); - - // PARSING - - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); - }); - - // HELPERS - - // MOMENTS - - function getSetDayOfYear (input) { - var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - } - - // FORMATTING - - addFormatToken('m', ['mm', 2], 0, 'minute'); - - // ALIASES - - addUnitAlias('minute', 'm'); - - // PRIORITY - - addUnitPriority('minute', 14); - - // PARSING - - addRegexToken('m', match1to2); - addRegexToken('mm', match1to2, match2); - addParseToken(['m', 'mm'], MINUTE); - - // MOMENTS - - var getSetMinute = makeGetSet('Minutes', false); - - // FORMATTING - - addFormatToken('s', ['ss', 2], 0, 'second'); - - // ALIASES - - addUnitAlias('second', 's'); - - // PRIORITY - - addUnitPriority('second', 15); - - // PARSING - - addRegexToken('s', match1to2); - addRegexToken('ss', match1to2, match2); - addParseToken(['s', 'ss'], SECOND); - - // MOMENTS - - var getSetSecond = makeGetSet('Seconds', false); - - // FORMATTING - - addFormatToken('S', 0, 0, function () { - return ~~(this.millisecond() / 100); - }); - - addFormatToken(0, ['SS', 2], 0, function () { - return ~~(this.millisecond() / 10); - }); - - addFormatToken(0, ['SSS', 3], 0, 'millisecond'); - addFormatToken(0, ['SSSS', 4], 0, function () { - return this.millisecond() * 10; - }); - addFormatToken(0, ['SSSSS', 5], 0, function () { - return this.millisecond() * 100; - }); - addFormatToken(0, ['SSSSSS', 6], 0, function () { - return this.millisecond() * 1000; - }); - addFormatToken(0, ['SSSSSSS', 7], 0, function () { - return this.millisecond() * 10000; - }); - addFormatToken(0, ['SSSSSSSS', 8], 0, function () { - return this.millisecond() * 100000; - }); - addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { - return this.millisecond() * 1000000; - }); - - - // ALIASES - - addUnitAlias('millisecond', 'ms'); - - // PRIORITY - - addUnitPriority('millisecond', 16); - - // PARSING - - addRegexToken('S', match1to3, match1); - addRegexToken('SS', match1to3, match2); - addRegexToken('SSS', match1to3, match3); - - var token; - for (token = 'SSSS'; token.length <= 9; token += 'S') { - addRegexToken(token, matchUnsigned); - } - - function parseMs(input, array) { - array[MILLISECOND] = toInt(('0.' + input) * 1000); - } - - for (token = 'S'; token.length <= 9; token += 'S') { - addParseToken(token, parseMs); - } - // MOMENTS - - var getSetMillisecond = makeGetSet('Milliseconds', false); - - // FORMATTING - - addFormatToken('z', 0, 0, 'zoneAbbr'); - addFormatToken('zz', 0, 0, 'zoneName'); - - // MOMENTS - - function getZoneAbbr () { - return this._isUTC ? 'UTC' : ''; - } - - function getZoneName () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - } - - var proto = Moment.prototype; - - proto.add = add; - proto.calendar = calendar$1; - proto.clone = clone; - proto.diff = diff; - proto.endOf = endOf; - proto.format = format; - proto.from = from; - proto.fromNow = fromNow; - proto.to = to; - proto.toNow = toNow; - proto.get = stringGet; - proto.invalidAt = invalidAt; - proto.isAfter = isAfter; - proto.isBefore = isBefore; - proto.isBetween = isBetween; - proto.isSame = isSame; - proto.isSameOrAfter = isSameOrAfter; - proto.isSameOrBefore = isSameOrBefore; - proto.isValid = isValid$2; - proto.lang = lang; - proto.locale = locale; - proto.localeData = localeData; - proto.max = prototypeMax; - proto.min = prototypeMin; - proto.parsingFlags = parsingFlags; - proto.set = stringSet; - proto.startOf = startOf; - proto.subtract = subtract; - proto.toArray = toArray; - proto.toObject = toObject; - proto.toDate = toDate; - proto.toISOString = toISOString; - proto.inspect = inspect; - proto.toJSON = toJSON; - proto.toString = toString; - proto.unix = unix; - proto.valueOf = valueOf; - proto.creationData = creationData; - proto.year = getSetYear; - proto.isLeapYear = getIsLeapYear; - proto.weekYear = getSetWeekYear; - proto.isoWeekYear = getSetISOWeekYear; - proto.quarter = proto.quarters = getSetQuarter; - proto.month = getSetMonth; - proto.daysInMonth = getDaysInMonth; - proto.week = proto.weeks = getSetWeek; - proto.isoWeek = proto.isoWeeks = getSetISOWeek; - proto.weeksInYear = getWeeksInYear; - proto.isoWeeksInYear = getISOWeeksInYear; - proto.date = getSetDayOfMonth; - proto.day = proto.days = getSetDayOfWeek; - proto.weekday = getSetLocaleDayOfWeek; - proto.isoWeekday = getSetISODayOfWeek; - proto.dayOfYear = getSetDayOfYear; - proto.hour = proto.hours = getSetHour; - proto.minute = proto.minutes = getSetMinute; - proto.second = proto.seconds = getSetSecond; - proto.millisecond = proto.milliseconds = getSetMillisecond; - proto.utcOffset = getSetOffset; - proto.utc = setOffsetToUTC; - proto.local = setOffsetToLocal; - proto.parseZone = setOffsetToParsedOffset; - proto.hasAlignedHourOffset = hasAlignedHourOffset; - proto.isDST = isDaylightSavingTime; - proto.isLocal = isLocal; - proto.isUtcOffset = isUtcOffset; - proto.isUtc = isUtc; - proto.isUTC = isUtc; - proto.zoneAbbr = getZoneAbbr; - proto.zoneName = getZoneName; - proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); - proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); - proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); - proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); - proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); - - function createUnix (input) { - return createLocal(input * 1000); - } - - function createInZone () { - return createLocal.apply(null, arguments).parseZone(); - } - - function preParsePostFormat (string) { - return string; - } - - var proto$1 = Locale.prototype; - - proto$1.calendar = calendar; - proto$1.longDateFormat = longDateFormat; - proto$1.invalidDate = invalidDate; - proto$1.ordinal = ordinal; - proto$1.preparse = preParsePostFormat; - proto$1.postformat = preParsePostFormat; - proto$1.relativeTime = relativeTime; - proto$1.pastFuture = pastFuture; - proto$1.set = set; - - proto$1.months = localeMonths; - proto$1.monthsShort = localeMonthsShort; - proto$1.monthsParse = localeMonthsParse; - proto$1.monthsRegex = monthsRegex; - proto$1.monthsShortRegex = monthsShortRegex; - proto$1.week = localeWeek; - proto$1.firstDayOfYear = localeFirstDayOfYear; - proto$1.firstDayOfWeek = localeFirstDayOfWeek; - - proto$1.weekdays = localeWeekdays; - proto$1.weekdaysMin = localeWeekdaysMin; - proto$1.weekdaysShort = localeWeekdaysShort; - proto$1.weekdaysParse = localeWeekdaysParse; - - proto$1.weekdaysRegex = weekdaysRegex; - proto$1.weekdaysShortRegex = weekdaysShortRegex; - proto$1.weekdaysMinRegex = weekdaysMinRegex; - - proto$1.isPM = localeIsPM; - proto$1.meridiem = localeMeridiem; - - function get$1 (format, index, field, setter) { - var locale = getLocale(); - var utc = createUTC().set(setter, index); - return locale[field](utc, format); - } - - function listMonthsImpl (format, index, field) { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - - if (index != null) { - return get$1(format, index, field, 'month'); - } - - var i; - var out = []; - for (i = 0; i < 12; i++) { - out[i] = get$1(format, i, field, 'month'); - } - return out; - } - - // () - // (5) - // (fmt, 5) - // (fmt) - // (true) - // (true, 5) - // (true, fmt, 5) - // (true, fmt) - function listWeekdaysImpl (localeSorted, format, index, field) { - if (typeof localeSorted === 'boolean') { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } else { - format = localeSorted; - index = format; - localeSorted = false; - - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } - - var locale = getLocale(), - shift = localeSorted ? locale._week.dow : 0; - - if (index != null) { - return get$1(format, (index + shift) % 7, field, 'day'); - } - - var i; - var out = []; - for (i = 0; i < 7; i++) { - out[i] = get$1(format, (i + shift) % 7, field, 'day'); - } - return out; - } - - function listMonths (format, index) { - return listMonthsImpl(format, index, 'months'); - } - - function listMonthsShort (format, index) { - return listMonthsImpl(format, index, 'monthsShort'); - } - - function listWeekdays (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); - } - - function listWeekdaysShort (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); - } - - function listWeekdaysMin (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); - } - - getSetGlobalLocale('en', { - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - // Side effect imports - - hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); - hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); - - var mathAbs = Math.abs; - - function abs () { - var data = this._data; - - this._milliseconds = mathAbs(this._milliseconds); - this._days = mathAbs(this._days); - this._months = mathAbs(this._months); - - data.milliseconds = mathAbs(data.milliseconds); - data.seconds = mathAbs(data.seconds); - data.minutes = mathAbs(data.minutes); - data.hours = mathAbs(data.hours); - data.months = mathAbs(data.months); - data.years = mathAbs(data.years); - - return this; - } - - function addSubtract$1 (duration, input, value, direction) { - var other = createDuration(input, value); - - duration._milliseconds += direction * other._milliseconds; - duration._days += direction * other._days; - duration._months += direction * other._months; - - return duration._bubble(); - } - - // supports only 2.0-style add(1, 's') or add(duration) - function add$1 (input, value) { - return addSubtract$1(this, input, value, 1); - } - - // supports only 2.0-style subtract(1, 's') or subtract(duration) - function subtract$1 (input, value) { - return addSubtract$1(this, input, value, -1); - } - - function absCeil (number) { - if (number < 0) { - return Math.floor(number); - } else { - return Math.ceil(number); - } - } - - function bubble () { - var milliseconds = this._milliseconds; - var days = this._days; - var months = this._months; - var data = this._data; - var seconds, minutes, hours, years, monthsFromDays; - - // if we have a mix of positive and negative values, bubble down first - // check: https://github.com/moment/moment/issues/2166 - if (!((milliseconds >= 0 && days >= 0 && months >= 0) || - (milliseconds <= 0 && days <= 0 && months <= 0))) { - milliseconds += absCeil(monthsToDays(months) + days) * 864e5; - days = 0; - months = 0; - } - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absFloor(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absFloor(seconds / 60); - data.minutes = minutes % 60; - - hours = absFloor(minutes / 60); - data.hours = hours % 24; - - days += absFloor(hours / 24); - - // convert days to months - monthsFromDays = absFloor(daysToMonths(days)); - months += monthsFromDays; - days -= absCeil(monthsToDays(monthsFromDays)); - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - data.days = days; - data.months = months; - data.years = years; - - return this; - } - - function daysToMonths (days) { - // 400 years have 146097 days (taking into account leap year rules) - // 400 years have 12 months === 4800 - return days * 4800 / 146097; - } - - function monthsToDays (months) { - // the reverse of daysToMonths - return months * 146097 / 4800; - } - - function as (units) { - if (!this.isValid()) { - return NaN; - } - var days; - var months; - var milliseconds = this._milliseconds; - - units = normalizeUnits(units); - - if (units === 'month' || units === 'year') { - days = this._days + milliseconds / 864e5; - months = this._months + daysToMonths(days); - return units === 'month' ? months : months / 12; - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(monthsToDays(this._months)); - switch (units) { - case 'week' : return days / 7 + milliseconds / 6048e5; - case 'day' : return days + milliseconds / 864e5; - case 'hour' : return days * 24 + milliseconds / 36e5; - case 'minute' : return days * 1440 + milliseconds / 6e4; - case 'second' : return days * 86400 + milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 864e5) + milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - } - - // TODO: Use this.as('ms')? - function valueOf$1 () { - if (!this.isValid()) { - return NaN; - } - return ( - this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6 - ); - } - - function makeAs (alias) { - return function () { - return this.as(alias); - }; - } - - var asMilliseconds = makeAs('ms'); - var asSeconds = makeAs('s'); - var asMinutes = makeAs('m'); - var asHours = makeAs('h'); - var asDays = makeAs('d'); - var asWeeks = makeAs('w'); - var asMonths = makeAs('M'); - var asYears = makeAs('y'); - - function clone$1 () { - return createDuration(this); - } - - function get$2 (units) { - units = normalizeUnits(units); - return this.isValid() ? this[units + 's']() : NaN; - } - - function makeGetter(name) { - return function () { - return this.isValid() ? this._data[name] : NaN; - }; - } - - var milliseconds = makeGetter('milliseconds'); - var seconds = makeGetter('seconds'); - var minutes = makeGetter('minutes'); - var hours = makeGetter('hours'); - var days = makeGetter('days'); - var months = makeGetter('months'); - var years = makeGetter('years'); - - function weeks () { - return absFloor(this.days() / 7); - } - - var round = Math.round; - var thresholds = { - ss: 44, // a few seconds to seconds - s : 45, // seconds to minute - m : 45, // minutes to hour - h : 22, // hours to day - d : 26, // days to month - M : 11 // months to year - }; - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime$1 (posNegDuration, withoutSuffix, locale) { - var duration = createDuration(posNegDuration).abs(); - var seconds = round(duration.as('s')); - var minutes = round(duration.as('m')); - var hours = round(duration.as('h')); - var days = round(duration.as('d')); - var months = round(duration.as('M')); - var years = round(duration.as('y')); - - var a = seconds <= thresholds.ss && ['s', seconds] || - seconds < thresholds.s && ['ss', seconds] || - minutes <= 1 && ['m'] || - minutes < thresholds.m && ['mm', minutes] || - hours <= 1 && ['h'] || - hours < thresholds.h && ['hh', hours] || - days <= 1 && ['d'] || - days < thresholds.d && ['dd', days] || - months <= 1 && ['M'] || - months < thresholds.M && ['MM', months] || - years <= 1 && ['y'] || ['yy', years]; - - a[2] = withoutSuffix; - a[3] = +posNegDuration > 0; - a[4] = locale; - return substituteTimeAgo.apply(null, a); - } - - // This function allows you to set the rounding function for relative time strings - function getSetRelativeTimeRounding (roundingFunction) { - if (roundingFunction === undefined) { - return round; - } - if (typeof(roundingFunction) === 'function') { - round = roundingFunction; - return true; - } - return false; - } - - // This function allows you to set a threshold for relative time strings - function getSetRelativeTimeThreshold (threshold, limit) { - if (thresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return thresholds[threshold]; - } - thresholds[threshold] = limit; - if (threshold === 's') { - thresholds.ss = limit - 1; - } - return true; - } - - function humanize (withSuffix) { - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var locale = this.localeData(); - var output = relativeTime$1(this, !withSuffix, locale); - - if (withSuffix) { - output = locale.pastFuture(+this, output); - } - - return locale.postformat(output); - } - - var abs$1 = Math.abs; - - function sign(x) { - return ((x > 0) - (x < 0)) || +x; - } - - function toISOString$1() { - // for ISO strings we do not use the normal bubbling rules: - // * milliseconds bubble up until they become hours - // * days do not bubble at all - // * months bubble up until they become years - // This is because there is no context-free conversion between hours and days - // (think of clock changes) - // and also not between days and months (28-31 days per month) - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var seconds = abs$1(this._milliseconds) / 1000; - var days = abs$1(this._days); - var months = abs$1(this._months); - var minutes, hours, years; - - // 3600 seconds -> 60 minutes -> 1 hour - minutes = absFloor(seconds / 60); - hours = absFloor(minutes / 60); - seconds %= 60; - minutes %= 60; - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var Y = years; - var M = months; - var D = days; - var h = hours; - var m = minutes; - var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; - var total = this.asSeconds(); - - if (!total) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - var totalSign = total < 0 ? '-' : ''; - var ymSign = sign(this._months) !== sign(total) ? '-' : ''; - var daysSign = sign(this._days) !== sign(total) ? '-' : ''; - var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - - return totalSign + 'P' + - (Y ? ymSign + Y + 'Y' : '') + - (M ? ymSign + M + 'M' : '') + - (D ? daysSign + D + 'D' : '') + - ((h || m || s) ? 'T' : '') + - (h ? hmsSign + h + 'H' : '') + - (m ? hmsSign + m + 'M' : '') + - (s ? hmsSign + s + 'S' : ''); - } - - var proto$2 = Duration.prototype; - - proto$2.isValid = isValid$1; - proto$2.abs = abs; - proto$2.add = add$1; - proto$2.subtract = subtract$1; - proto$2.as = as; - proto$2.asMilliseconds = asMilliseconds; - proto$2.asSeconds = asSeconds; - proto$2.asMinutes = asMinutes; - proto$2.asHours = asHours; - proto$2.asDays = asDays; - proto$2.asWeeks = asWeeks; - proto$2.asMonths = asMonths; - proto$2.asYears = asYears; - proto$2.valueOf = valueOf$1; - proto$2._bubble = bubble; - proto$2.clone = clone$1; - proto$2.get = get$2; - proto$2.milliseconds = milliseconds; - proto$2.seconds = seconds; - proto$2.minutes = minutes; - proto$2.hours = hours; - proto$2.days = days; - proto$2.weeks = weeks; - proto$2.months = months; - proto$2.years = years; - proto$2.humanize = humanize; - proto$2.toISOString = toISOString$1; - proto$2.toString = toISOString$1; - proto$2.toJSON = toISOString$1; - proto$2.locale = locale; - proto$2.localeData = localeData; - - proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); - proto$2.lang = lang; - - // Side effect imports - - // FORMATTING - - addFormatToken('X', 0, 0, 'unix'); - addFormatToken('x', 0, 0, 'valueOf'); - - // PARSING - - addRegexToken('x', matchSigned); - addRegexToken('X', matchTimestamp); - addParseToken('X', function (input, array, config) { - config._d = new Date(parseFloat(input, 10) * 1000); - }); - addParseToken('x', function (input, array, config) { - config._d = new Date(toInt(input)); - }); - - // Side effect imports - - - hooks.version = '2.22.2'; - - setHookCallback(createLocal); - - hooks.fn = proto; - hooks.min = min; - hooks.max = max; - hooks.now = now; - hooks.utc = createUTC; - hooks.unix = createUnix; - hooks.months = listMonths; - hooks.isDate = isDate; - hooks.locale = getSetGlobalLocale; - hooks.invalid = createInvalid; - hooks.duration = createDuration; - hooks.isMoment = isMoment; - hooks.weekdays = listWeekdays; - hooks.parseZone = createInZone; - hooks.localeData = getLocale; - hooks.isDuration = isDuration; - hooks.monthsShort = listMonthsShort; - hooks.weekdaysMin = listWeekdaysMin; - hooks.defineLocale = defineLocale; - hooks.updateLocale = updateLocale; - hooks.locales = listLocales; - hooks.weekdaysShort = listWeekdaysShort; - hooks.normalizeUnits = normalizeUnits; - hooks.relativeTimeRounding = getSetRelativeTimeRounding; - hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; - hooks.calendarFormat = getCalendarFormat; - hooks.prototype = proto; - - // currently HTML5 input type only supports 24-hour formats - hooks.HTML5_FMT = { - DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // <input type="datetime-local" /> - DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // <input type="datetime-local" step="1" /> - DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // <input type="datetime-local" step="0.001" /> - DATE: 'YYYY-MM-DD', // <input type="date" /> - TIME: 'HH:mm', // <input type="time" /> - TIME_SECONDS: 'HH:mm:ss', // <input type="time" step="1" /> - TIME_MS: 'HH:mm:ss.SSS', // <input type="time" step="0.001" /> - WEEK: 'YYYY-[W]WW', // <input type="week" /> - MONTH: 'YYYY-MM' // <input type="month" /> - }; - - return hooks; - -}))); - -},{}],7:[function(require,module,exports){ -/** - * @namespace Chart - */ -var Chart = require(30)(); - -Chart.helpers = require(46); - -// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests! -require(28)(Chart); - -Chart.Animation = require(22); -Chart.animationService = require(23); -Chart.defaults = require(26); -Chart.Element = require(27); -Chart.elements = require(41); -Chart.Interaction = require(29); -Chart.layouts = require(31); -Chart.platform = require(49); -Chart.plugins = require(32); -Chart.Scale = require(33); -Chart.scaleService = require(34); -Chart.Ticks = require(35); -Chart.Tooltip = require(36); - -require(24)(Chart); -require(25)(Chart); - -require(56)(Chart); -require(54)(Chart); -require(55)(Chart); -require(57)(Chart); -require(58)(Chart); -require(59)(Chart); - -// Controllers must be loaded after elements -// See Chart.core.datasetController.dataElementType -require(15)(Chart); -require(16)(Chart); -require(17)(Chart); -require(18)(Chart); -require(19)(Chart); -require(20)(Chart); -require(21)(Chart); - -require(8)(Chart); -require(9)(Chart); -require(10)(Chart); -require(11)(Chart); -require(12)(Chart); -require(13)(Chart); -require(14)(Chart); - -// Loading built-in plugins -var plugins = require(50); -for (var k in plugins) { - if (plugins.hasOwnProperty(k)) { - Chart.plugins.register(plugins[k]); - } -} - -Chart.platform.initialize(); - -module.exports = Chart; -if (typeof window !== 'undefined') { - window.Chart = Chart; -} - -// DEPRECATIONS - -/** - * Provided for backward compatibility, not available anymore - * @namespace Chart.Legend - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -Chart.Legend = plugins.legend._element; - -/** - * Provided for backward compatibility, not available anymore - * @namespace Chart.Title - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -Chart.Title = plugins.title._element; - -/** - * Provided for backward compatibility, use Chart.plugins instead - * @namespace Chart.pluginService - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -Chart.pluginService = Chart.plugins; - -/** - * Provided for backward compatibility, inheriting from Chart.PlugingBase has no - * effect, instead simply create/register plugins via plain JavaScript objects. - * @interface Chart.PluginBase - * @deprecated since version 2.5.0 - * @todo remove at version 3 - * @private - */ -Chart.PluginBase = Chart.Element.extend({}); - -/** - * Provided for backward compatibility, use Chart.helpers.canvas instead. - * @namespace Chart.canvasHelpers - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ -Chart.canvasHelpers = Chart.helpers.canvas; - -/** - * Provided for backward compatibility, use Chart.layouts instead. - * @namespace Chart.layoutService - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ -Chart.layoutService = Chart.layouts; - -},{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"41":41,"46":46,"49":49,"50":50,"54":54,"55":55,"56":56,"57":57,"58":58,"59":59,"8":8,"9":9}],8:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.Bar = function(context, config) { - config.type = 'bar'; - - return new Chart(context, config); - }; - -}; - -},{}],9:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.Bubble = function(context, config) { - config.type = 'bubble'; - return new Chart(context, config); - }; - -}; - -},{}],10:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.Doughnut = function(context, config) { - config.type = 'doughnut'; - - return new Chart(context, config); - }; - -}; - -},{}],11:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.Line = function(context, config) { - config.type = 'line'; - - return new Chart(context, config); - }; - -}; - -},{}],12:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.PolarArea = function(context, config) { - config.type = 'polarArea'; - - return new Chart(context, config); - }; - -}; - -},{}],13:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - - Chart.Radar = function(context, config) { - config.type = 'radar'; - - return new Chart(context, config); - }; - -}; - -},{}],14:[function(require,module,exports){ -'use strict'; - -module.exports = function(Chart) { - Chart.Scatter = function(context, config) { - config.type = 'scatter'; - return new Chart(context, config); - }; -}; - -},{}],15:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('bar', { - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - - // Specific to Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // offset settings - offset: true, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }], - - yAxes: [{ - type: 'linear' - }] - } -}); - -defaults._set('horizontalBar', { - hover: { - mode: 'index', - axis: 'y' - }, - - scales: { - xAxes: [{ - type: 'linear', - position: 'bottom' - }], - - yAxes: [{ - position: 'left', - type: 'category', - - // Specific to Horizontal Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // offset settings - offset: true, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }] - }, - - elements: { - rectangle: { - borderSkipped: 'left' - } - }, - - tooltips: { - callbacks: { - title: function(item, data) { - // Pick first xLabel for now - var title = ''; - - if (item.length > 0) { - if (item[0].yLabel) { - title = item[0].yLabel; - } else if (data.labels.length > 0 && item[0].index < data.labels.length) { - title = data.labels[item[0].index]; - } - } - - return title; - }, - - label: function(item, data) { - var datasetLabel = data.datasets[item.datasetIndex].label || ''; - return datasetLabel + ': ' + item.xLabel; - } - }, - mode: 'index', - axis: 'y' - } -}); - -/** - * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. - * @private - */ -function computeMinSampleSize(scale, pixels) { - var min = scale.isHorizontal() ? scale.width : scale.height; - var ticks = scale.getTicks(); - var prev, curr, i, ilen; - - for (i = 1, ilen = pixels.length; i < ilen; ++i) { - min = Math.min(min, pixels[i] - pixels[i - 1]); - } - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - curr = scale.getPixelForTick(i); - min = i > 0 ? Math.min(min, curr - prev) : min; - prev = curr; - } - - return min; -} - -/** - * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, - * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This - * mode currently always generates bars equally sized (until we introduce scriptable options?). - * @private - */ -function computeFitCategoryTraits(index, ruler, options) { - var thickness = options.barThickness; - var count = ruler.stackCount; - var curr = ruler.pixels[index]; - var size, ratio; - - if (helpers.isNullOrUndef(thickness)) { - size = ruler.min * options.categoryPercentage; - ratio = options.barPercentage; - } else { - // When bar thickness is enforced, category and bar percentages are ignored. - // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') - // and deprecate barPercentage since this value is ignored when thickness is absolute. - size = thickness * count; - ratio = 1; - } - - return { - chunk: size / count, - ratio: ratio, - start: curr - (size / 2) - }; -} - -/** - * Computes an "optimal" category that globally arranges bars side by side (no gap when - * percentage options are 1), based on the previous and following categories. This mode - * generates bars with different widths when data are not evenly spaced. - * @private - */ -function computeFlexCategoryTraits(index, ruler, options) { - var pixels = ruler.pixels; - var curr = pixels[index]; - var prev = index > 0 ? pixels[index - 1] : null; - var next = index < pixels.length - 1 ? pixels[index + 1] : null; - var percent = options.categoryPercentage; - var start, size; - - if (prev === null) { - // first data: its size is double based on the next point or, - // if it's also the last data, we use the scale end extremity. - prev = curr - (next === null ? ruler.end - curr : next - curr); - } - - if (next === null) { - // last data: its size is also double based on the previous point. - next = curr + curr - prev; - } - - start = curr - ((curr - prev) / 2) * percent; - size = ((next - prev) / 2) * percent; - - return { - chunk: size / ruler.stackCount, - ratio: options.barPercentage, - start: start - }; -} - -module.exports = function(Chart) { - - Chart.controllers.bar = Chart.DatasetController.extend({ - - dataElementType: elements.Rectangle, - - initialize: function() { - var me = this; - var meta; - - Chart.DatasetController.prototype.initialize.apply(me, arguments); - - meta = me.getMeta(); - meta.stack = me.getDataset().stack; - meta.bar = true; - }, - - update: function(reset) { - var me = this; - var rects = me.getMeta().data; - var i, ilen; - - me._ruler = me.getRuler(); - - for (i = 0, ilen = rects.length; i < ilen; ++i) { - me.updateElement(rects[i], i, reset); - } - }, - - updateElement: function(rectangle, index, reset) { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var dataset = me.getDataset(); - var custom = rectangle.custom || {}; - var rectangleOptions = chart.options.elements.rectangle; - - rectangle._xScale = me.getScaleForId(meta.xAxisID); - rectangle._yScale = me.getScaleForId(meta.yAxisID); - rectangle._datasetIndex = me.index; - rectangle._index = index; - - rectangle._model = { - datasetLabel: dataset.label, - label: chart.data.labels[index], - borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleOptions.borderSkipped, - backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.backgroundColor, index, rectangleOptions.backgroundColor), - borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.borderColor, index, rectangleOptions.borderColor), - borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.borderWidth, index, rectangleOptions.borderWidth) - }; - - me.updateElementGeometry(rectangle, index, reset); - - rectangle.pivot(); - }, - - /** - * @private - */ - updateElementGeometry: function(rectangle, index, reset) { - var me = this; - var model = rectangle._model; - var vscale = me.getValueScale(); - var base = vscale.getBasePixel(); - var horizontal = vscale.isHorizontal(); - var ruler = me._ruler || me.getRuler(); - var vpixels = me.calculateBarValuePixels(me.index, index); - var ipixels = me.calculateBarIndexPixels(me.index, index, ruler); - - model.horizontal = horizontal; - model.base = reset ? base : vpixels.base; - model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; - model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; - model.height = horizontal ? ipixels.size : undefined; - model.width = horizontal ? undefined : ipixels.size; - }, - - /** - * @private - */ - getValueScaleId: function() { - return this.getMeta().yAxisID; - }, - - /** - * @private - */ - getIndexScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - getValueScale: function() { - return this.getScaleForId(this.getValueScaleId()); - }, - - /** - * @private - */ - getIndexScale: function() { - return this.getScaleForId(this.getIndexScaleId()); - }, - - /** - * Returns the stacks based on groups and bar visibility. - * @param {Number} [last] - The dataset index - * @returns {Array} The stack list - * @private - */ - _getStacks: function(last) { - var me = this; - var chart = me.chart; - var scale = me.getIndexScale(); - var stacked = scale.options.stacked; - var ilen = last === undefined ? chart.data.datasets.length : last + 1; - var stacks = []; - var i, meta; - - for (i = 0; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - if (meta.bar && chart.isDatasetVisible(i) && - (stacked === false || - (stacked === true && stacks.indexOf(meta.stack) === -1) || - (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) { - stacks.push(meta.stack); - } - } - - return stacks; - }, - - /** - * Returns the effective number of stacks based on groups and bar visibility. - * @private - */ - getStackCount: function() { - return this._getStacks().length; - }, - - /** - * Returns the stack index for the given dataset based on groups and bar visibility. - * @param {Number} [datasetIndex] - The dataset index - * @param {String} [name] - The stack name to find - * @returns {Number} The stack index - * @private - */ - getStackIndex: function(datasetIndex, name) { - var stacks = this._getStacks(datasetIndex); - var index = (name !== undefined) - ? stacks.indexOf(name) - : -1; // indexOf returns -1 if element is not present - - return (index === -1) - ? stacks.length - 1 - : index; - }, - - /** - * @private - */ - getRuler: function() { - var me = this; - var scale = me.getIndexScale(); - var stackCount = me.getStackCount(); - var datasetIndex = me.index; - var isHorizontal = scale.isHorizontal(); - var start = isHorizontal ? scale.left : scale.top; - var end = start + (isHorizontal ? scale.width : scale.height); - var pixels = []; - var i, ilen, min; - - for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { - pixels.push(scale.getPixelForValue(null, i, datasetIndex)); - } - - min = helpers.isNullOrUndef(scale.options.barThickness) - ? computeMinSampleSize(scale, pixels) - : -1; - - return { - min: min, - pixels: pixels, - start: start, - end: end, - stackCount: stackCount, - scale: scale - }; - }, - - /** - * Note: pixel values are not clamped to the scale area. - * @private - */ - calculateBarValuePixels: function(datasetIndex, index) { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var scale = me.getValueScale(); - var datasets = chart.data.datasets; - var value = scale.getRightValue(datasets[datasetIndex].data[index]); - var stacked = scale.options.stacked; - var stack = meta.stack; - var start = 0; - var i, imeta, ivalue, base, head, size; - - if (stacked || (stacked === undefined && stack !== undefined)) { - for (i = 0; i < datasetIndex; ++i) { - imeta = chart.getDatasetMeta(i); - - if (imeta.bar && - imeta.stack === stack && - imeta.controller.getValueScaleId() === scale.id && - chart.isDatasetVisible(i)) { - - ivalue = scale.getRightValue(datasets[i].data[index]); - if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) { - start += ivalue; - } - } - } - } - - base = scale.getPixelForValue(start); - head = scale.getPixelForValue(start + value); - size = (head - base) / 2; - - return { - size: size, - base: base, - head: head, - center: head + size / 2 - }; - }, - - /** - * @private - */ - calculateBarIndexPixels: function(datasetIndex, index, ruler) { - var me = this; - var options = ruler.scale.options; - var range = options.barThickness === 'flex' - ? computeFlexCategoryTraits(index, ruler, options) - : computeFitCategoryTraits(index, ruler, options); - - var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); - var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); - var size = Math.min( - helpers.valueOrDefault(options.maxBarThickness, Infinity), - range.chunk * range.ratio); - - return { - base: center - size / 2, - head: center + size / 2, - center: center, - size: size - }; - }, - - draw: function() { - var me = this; - var chart = me.chart; - var scale = me.getValueScale(); - var rects = me.getMeta().data; - var dataset = me.getDataset(); - var ilen = rects.length; - var i = 0; - - helpers.canvas.clipArea(chart.ctx, chart.chartArea); - - for (; i < ilen; ++i) { - if (!isNaN(scale.getRightValue(dataset.data[i]))) { - rects[i].draw(); - } - } - - helpers.canvas.unclipArea(chart.ctx); - }, - }); - - Chart.controllers.horizontalBar = Chart.controllers.bar.extend({ - /** - * @private - */ - getValueScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - getIndexScaleId: function() { - return this.getMeta().yAxisID; - } - }); -}; - -},{"26":26,"41":41,"46":46}],16:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('bubble', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: 'linear', // bubble should probably use a linear scale by default - position: 'bottom', - id: 'x-axis-0' // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: 'linear', - position: 'left', - id: 'y-axis-0' - }] - }, - - tooltips: { - callbacks: { - title: function() { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(item, data) { - var datasetLabel = data.datasets[item.datasetIndex].label || ''; - var dataPoint = data.datasets[item.datasetIndex].data[item.index]; - return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; - } - } - } -}); - - -module.exports = function(Chart) { - - Chart.controllers.bubble = Chart.DatasetController.extend({ - /** - * @protected - */ - dataElementType: elements.Point, - - /** - * @protected - */ - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var points = meta.data; - - // Update Points - helpers.each(points, function(point, index) { - me.updateElement(point, index, reset); - }); - }, - - /** - * @protected - */ - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var xScale = me.getScaleForId(meta.xAxisID); - var yScale = me.getScaleForId(meta.yAxisID); - var options = me._resolveElementOptions(point, index); - var data = me.getDataset().data[index]; - var dsIndex = me.index; - - var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); - var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); - - point._xScale = xScale; - point._yScale = yScale; - point._options = options; - point._datasetIndex = dsIndex; - point._index = index; - point._model = { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - hitRadius: options.hitRadius, - pointStyle: options.pointStyle, - rotation: options.rotation, - radius: reset ? 0 : options.radius, - skip: custom.skip || isNaN(x) || isNaN(y), - x: x, - y: y, - }; - - point.pivot(); - }, - - /** - * @protected - */ - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - model.backgroundColor = helpers.valueOrDefault(options.hoverBackgroundColor, helpers.getHoverColor(options.backgroundColor)); - model.borderColor = helpers.valueOrDefault(options.hoverBorderColor, helpers.getHoverColor(options.borderColor)); - model.borderWidth = helpers.valueOrDefault(options.hoverBorderWidth, options.borderWidth); - model.radius = options.radius + options.hoverRadius; - }, - - /** - * @private - */ - _resolveElementOptions: function(point, index) { - var me = this; - var chart = me.chart; - var datasets = chart.data.datasets; - var dataset = datasets[me.index]; - var custom = point.custom || {}; - var options = chart.options.elements.point; - var resolve = helpers.options.resolve; - var data = dataset.data[index]; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var keys = [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - 'hoverRadius', - 'hitRadius', - 'pointStyle', - 'rotation' - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve([ - custom[key], - dataset[key], - options[key] - ], context, index); - } - - // Custom radius resolution - values.radius = resolve([ - custom.radius, - data ? data.r : undefined, - dataset.radius, - options.radius - ], context, index); - return values; - } - }); -}; - -},{"26":26,"41":41,"46":46}],17:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('doughnut', { - animation: { - // Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - // Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var text = []; - text.push('<ul class="' + chart.id + '-legend">'); - - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - - if (datasets.length) { - for (var i = 0; i < datasets[0].data.length; ++i) { - text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>'); - if (labels[i]) { - text.push(labels[i]); - } - text.push('</li>'); - } - } - - text.push('</ul>'); - return text.join(''); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var custom = arc && arc.custom || {}; - var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - var arcOpts = chart.options.elements.arc; - var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); - var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); - var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - // toggle visibility of index if exists - if (meta.data[index]) { - meta.data[index].hidden = !meta.data[index].hidden; - } - } - - chart.update(); - } - }, - - // The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - // The rotation of the chart, where the first data arc begins. - rotation: Math.PI * -0.5, - - // The total circumference of the chart. - circumference: Math.PI * 2.0, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - var dataLabel = data.labels[tooltipItem.index]; - var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - - if (helpers.isArray(dataLabel)) { - // show value on first line of multiline label - // need to clone because we are changing the value - dataLabel = dataLabel.slice(); - dataLabel[0] += value; - } else { - dataLabel += value; - } - - return dataLabel; - } - } - } -}); - -defaults._set('pie', helpers.clone(defaults.doughnut)); -defaults._set('pie', { - cutoutPercentage: 0 -}); - -module.exports = function(Chart) { - - Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers.noop, - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (this.chart.isDatasetVisible(j)) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function(reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var arcOpts = opts.elements.arc; - var availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth; - var availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth; - var minSize = Math.min(availableWidth, availableHeight); - var offset = {x: 0, y: 0}; - var meta = me.getMeta(); - var cutoutPercentage = opts.cutoutPercentage; - var circumference = opts.circumference; - - // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc - if (circumference < Math.PI * 2.0) { - var startAngle = opts.rotation % (Math.PI * 2.0); - startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); - var endAngle = startAngle + circumference; - var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; - var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; - var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); - var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); - var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); - var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); - var cutout = cutoutPercentage / 100.0; - var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; - var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; - var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; - minSize = Math.min(availableWidth / size.width, availableHeight / size.height); - offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; - } - - chart.borderWidth = me.getMaxBorderWidth(meta.data); - chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0); - chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); - chart.offsetX = offset.x * chart.outerRadius; - chart.offsetY = offset.y * chart.outerRadius; - - meta.total = me.calculateTotal(); - - me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index)); - me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0); - - helpers.each(meta.data, function(arc, index) { - me.updateElement(arc, index, reset); - }); - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var animationOpts = opts.animation; - var centerX = (chartArea.left + chartArea.right) / 2; - var centerY = (chartArea.top + chartArea.bottom) / 2; - var startAngle = opts.rotation; // non reset case handled later - var endAngle = opts.rotation; // non reset case handled later - var dataset = me.getDataset(); - var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)); - var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; - var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; - var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - - helpers.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - - // Desired view properties - _model: { - x: centerX + chart.offsetX, - y: centerY + chart.offsetY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) - } - }); - - var model = arc._model; - - // Resets the visual styles - var custom = arc.custom || {}; - var valueOrDefault = helpers.valueAtIndexOrDefault; - var elementOpts = this.chart.options.elements.arc; - model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor); - model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor); - model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth); - - // Set correct angles if not resetting - if (!reset || !animationOpts.animateRotate) { - if (index === 0) { - model.startAngle = opts.rotation; - } else { - model.startAngle = me.getMeta().data[index - 1]._model.endAngle; - } - - model.endAngle = model.startAngle + model.circumference; - } - - arc.pivot(); - }, - - calculateTotal: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var total = 0; - var value; - - helpers.each(meta.data, function(element, index) { - value = dataset.data[index]; - if (!isNaN(value) && !element.hidden) { - total += Math.abs(value); - } - }); - - /* if (total === 0) { - total = NaN; - }*/ - - return total; - }, - - calculateCircumference: function(value) { - var total = this.getMeta().total; - if (total > 0 && !isNaN(value)) { - return (Math.PI * 2.0) * (Math.abs(value) / total); - } - return 0; - }, - - // gets the max border or hover width to properly scale pie charts - getMaxBorderWidth: function(arcs) { - var max = 0; - var index = this.index; - var length = arcs.length; - var borderWidth; - var hoverWidth; - - for (var i = 0; i < length; i++) { - borderWidth = arcs[i]._model ? arcs[i]._model.borderWidth : 0; - hoverWidth = arcs[i]._chart ? arcs[i]._chart.config.data.datasets[index].hoverBorderWidth : 0; - - max = borderWidth > max ? borderWidth : max; - max = hoverWidth > max ? hoverWidth : max; - } - return max; - } - }); -}; - -},{"26":26,"41":41,"46":46}],18:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('line', { - showLines: true, - spanGaps: false, - - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - id: 'x-axis-0' - }], - yAxes: [{ - type: 'linear', - id: 'y-axis-0' - }] - } -}); - -module.exports = function(Chart) { - - function lineEnabled(dataset, options) { - return helpers.valueOrDefault(dataset.showLine, options.showLines); - } - - Chart.controllers.line = Chart.DatasetController.extend({ - - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data || []; - var options = me.chart.options; - var lineElementOptions = options.elements.line; - var scale = me.getScaleForId(meta.yAxisID); - var i, ilen, custom; - var dataset = me.getDataset(); - var showLine = lineEnabled(dataset, options); - - // Update Line - if (showLine) { - custom = line.custom || {}; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { - dataset.lineTension = dataset.tension; - } - - // Utility - line._scale = scale; - line._datasetIndex = me.index; - // Data - line._children = points; - // Model - line._model = { - // Appearance - // The default behavior of lines is to break at null values, according - // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 - // This option gives lines the ability to span gaps - spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps, - tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension), - backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), - borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), - borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), - borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), - borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), - borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), - borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), - fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), - steppedLine: custom.steppedLine ? custom.steppedLine : helpers.valueOrDefault(dataset.steppedLine, lineElementOptions.stepped), - cubicInterpolationMode: custom.cubicInterpolationMode ? custom.cubicInterpolationMode : helpers.valueOrDefault(dataset.cubicInterpolationMode, lineElementOptions.cubicInterpolationMode), - }; - - line.pivot(); - } - - // Update Points - for (i = 0, ilen = points.length; i < ilen; ++i) { - me.updateElement(points[i], i, reset); - } - - if (showLine && line._model.tension !== 0) { - me.updateBezierControlPoints(); - } - - // Now pivot the point for animation - for (i = 0, ilen = points.length; i < ilen; ++i) { - points[i].pivot(); - } - }, - - getPointBackgroundColor: function(point, index) { - var backgroundColor = this.chart.options.elements.point.backgroundColor; - var dataset = this.getDataset(); - var custom = point.custom || {}; - - if (custom.backgroundColor) { - backgroundColor = custom.backgroundColor; - } else if (dataset.pointBackgroundColor) { - backgroundColor = helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); - } else if (dataset.backgroundColor) { - backgroundColor = dataset.backgroundColor; - } - - return backgroundColor; - }, - - getPointBorderColor: function(point, index) { - var borderColor = this.chart.options.elements.point.borderColor; - var dataset = this.getDataset(); - var custom = point.custom || {}; - - if (custom.borderColor) { - borderColor = custom.borderColor; - } else if (dataset.pointBorderColor) { - borderColor = helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor); - } else if (dataset.borderColor) { - borderColor = dataset.borderColor; - } - - return borderColor; - }, - - getPointBorderWidth: function(point, index) { - var borderWidth = this.chart.options.elements.point.borderWidth; - var dataset = this.getDataset(); - var custom = point.custom || {}; - - if (!isNaN(custom.borderWidth)) { - borderWidth = custom.borderWidth; - } else if (!isNaN(dataset.pointBorderWidth) || helpers.isArray(dataset.pointBorderWidth)) { - borderWidth = helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); - } else if (!isNaN(dataset.borderWidth)) { - borderWidth = dataset.borderWidth; - } - - return borderWidth; - }, - - getPointRotation: function(point, index) { - var pointRotation = this.chart.options.elements.point.rotation; - var dataset = this.getDataset(); - var custom = point.custom || {}; - - if (!isNaN(custom.rotation)) { - pointRotation = custom.rotation; - } else if (!isNaN(dataset.pointRotation) || helpers.isArray(dataset.pointRotation)) { - pointRotation = helpers.valueAtIndexOrDefault(dataset.pointRotation, index, pointRotation); - } - return pointRotation; - }, - - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var dataset = me.getDataset(); - var datasetIndex = me.index; - var value = dataset.data[index]; - var yScale = me.getScaleForId(meta.yAxisID); - var xScale = me.getScaleForId(meta.xAxisID); - var pointOptions = me.chart.options.elements.point; - var x, y; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { - dataset.pointRadius = dataset.radius; - } - if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { - dataset.pointHitRadius = dataset.hitRadius; - } - - x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); - y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); - - // Utility - point._xScale = xScale; - point._yScale = yScale; - point._datasetIndex = datasetIndex; - point._index = index; - - // Desired view properties - point._model = { - x: x, - y: y, - skip: custom.skip || isNaN(x) || isNaN(y), - // Appearance - radius: custom.radius || helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointOptions.radius), - pointStyle: custom.pointStyle || helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointOptions.pointStyle), - rotation: me.getPointRotation(point, index), - backgroundColor: me.getPointBackgroundColor(point, index), - borderColor: me.getPointBorderColor(point, index), - borderWidth: me.getPointBorderWidth(point, index), - tension: meta.dataset._model ? meta.dataset._model.tension : 0, - steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false, - // Tooltip - hitRadius: custom.hitRadius || helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius) - }; - }, - - calculatePointY: function(value, index, datasetIndex) { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var yScale = me.getScaleForId(meta.yAxisID); - var sumPos = 0; - var sumNeg = 0; - var i, ds, dsMeta; - - if (yScale.options.stacked) { - for (i = 0; i < datasetIndex; i++) { - ds = chart.data.datasets[i]; - dsMeta = chart.getDatasetMeta(i); - if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { - var stackedRightValue = Number(yScale.getRightValue(ds.data[index])); - if (stackedRightValue < 0) { - sumNeg += stackedRightValue || 0; - } else { - sumPos += stackedRightValue || 0; - } - } - } - - var rightValue = Number(yScale.getRightValue(value)); - if (rightValue < 0) { - return yScale.getPixelForValue(sumNeg + rightValue); - } - return yScale.getPixelForValue(sumPos + rightValue); - } - - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - var me = this; - var meta = me.getMeta(); - var area = me.chart.chartArea; - var points = (meta.data || []); - var i, ilen, point, model, controlPoints; - - // Only consider points that are drawn in case the spanGaps option is used - if (meta.dataset._model.spanGaps) { - points = points.filter(function(pt) { - return !pt._model.skip; - }); - } - - function capControlPoint(pt, min, max) { - return Math.max(Math.min(pt, max), min); - } - - if (meta.dataset._model.cubicInterpolationMode === 'monotone') { - helpers.splineCurveMonotone(points); - } else { - for (i = 0, ilen = points.length; i < ilen; ++i) { - point = points[i]; - model = point._model; - controlPoints = helpers.splineCurve( - helpers.previousItem(points, i)._model, - model, - helpers.nextItem(points, i)._model, - meta.dataset._model.tension - ); - model.controlPointPreviousX = controlPoints.previous.x; - model.controlPointPreviousY = controlPoints.previous.y; - model.controlPointNextX = controlPoints.next.x; - model.controlPointNextY = controlPoints.next.y; - } - } - - if (me.chart.options.elements.line.capBezierPoints) { - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); - model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); - model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); - model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); - } - } - }, - - draw: function() { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var points = meta.data || []; - var area = chart.chartArea; - var ilen = points.length; - var halfBorderWidth; - var i = 0; - - if (lineEnabled(me.getDataset(), chart.options)) { - halfBorderWidth = (meta.dataset._model.borderWidth || 0) / 2; - - helpers.canvas.clipArea(chart.ctx, { - left: area.left, - right: area.right, - top: area.top - halfBorderWidth, - bottom: area.bottom + halfBorderWidth - }); - - meta.dataset.draw(); - - helpers.canvas.unclipArea(chart.ctx); - } - - // Draw the points - for (; i < ilen; ++i) { - points[i].draw(area); - } - }, - - setHoverStyle: function(element) { - // Point - var dataset = this.chart.data.datasets[element._datasetIndex]; - var index = element._index; - var custom = element.custom || {}; - var model = element._model; - - element.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = custom.hoverBackgroundColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); - model.borderColor = custom.hoverBorderColor || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); - model.borderWidth = custom.hoverBorderWidth || helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); - model.radius = custom.hoverRadius || helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - }, - }); -}; - -},{"26":26,"41":41,"46":46}],19:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('polarArea', { - scale: { - type: 'radialLinear', - angleLines: { - display: false - }, - gridLines: { - circular: true - }, - pointLabels: { - display: false - }, - ticks: { - beginAtZero: true - } - }, - - // Boolean - Whether to animate the rotation of the chart - animation: { - animateRotate: true, - animateScale: true - }, - - startAngle: -0.5 * Math.PI, - legendCallback: function(chart) { - var text = []; - text.push('<ul class="' + chart.id + '-legend">'); - - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - - if (datasets.length) { - for (var i = 0; i < datasets[0].data.length; ++i) { - text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>'); - if (labels[i]) { - text.push(labels[i]); - } - text.push('</li>'); - } - } - - text.push('</ul>'); - return text.join(''); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var custom = arc.custom || {}; - var valueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - var arcOpts = chart.options.elements.arc; - var fill = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); - var stroke = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); - var bw = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(item, data) { - return data.labels[item.index] + ': ' + item.yLabel; - } - } - } -}); - -module.exports = function(Chart) { - - Chart.controllers.polarArea = Chart.DatasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers.noop, - - update: function(reset) { - var me = this; - var dataset = me.getDataset(); - var meta = me.getMeta(); - var start = me.chart.options.startAngle || 0; - var starts = me._starts = []; - var angles = me._angles = []; - var i, ilen, angle; - - me._updateRadius(); - - meta.count = me.countVisibleElements(); - - for (i = 0, ilen = dataset.data.length; i < ilen; i++) { - starts[i] = start; - angle = me._computeAngle(i); - angles[i] = angle; - start += angle; - } - - helpers.each(meta.data, function(arc, index) { - me.updateElement(arc, index, reset); - }); - }, - - /** - * @private - */ - _updateRadius: function() { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var arcOpts = opts.elements.arc; - var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); - - chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0); - chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); - - me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); - me.innerRadius = me.outerRadius - chart.radiusLength; - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var opts = chart.options; - var animationOpts = opts.animation; - var scale = chart.scale; - var labels = chart.data.labels; - - var centerX = scale.xCenter; - var centerY = scale.yCenter; - - // var negHalfPI = -0.5 * Math.PI; - var datasetStartAngle = opts.startAngle; - var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - var startAngle = me._starts[index]; - var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]); - - var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - - helpers.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - _scale: scale, - - // Desired view properties - _model: { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: reset ? resetRadius : distance, - startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, - endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, - label: helpers.valueAtIndexOrDefault(labels, index, labels[index]) - } - }); - - // Apply border and fill style - var elementOpts = this.chart.options.elements.arc; - var custom = arc.custom || {}; - var valueOrDefault = helpers.valueAtIndexOrDefault; - var model = arc._model; - - model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor); - model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor); - model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth); - - arc.pivot(); - }, - - countVisibleElements: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var count = 0; - - helpers.each(meta.data, function(element, index) { - if (!isNaN(dataset.data[index]) && !element.hidden) { - count++; - } - }); - - return count; - }, - - /** - * @private - */ - _computeAngle: function(index) { - var me = this; - var count = this.getMeta().count; - var dataset = me.getDataset(); - var meta = me.getMeta(); - - if (isNaN(dataset.data[index]) || meta.data[index].hidden) { - return 0; - } - - // Scriptable options - var context = { - chart: me.chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - return helpers.options.resolve([ - me.chart.options.elements.arc.angle, - (2 * Math.PI) / count - ], context, index); - } - }); -}; - -},{"26":26,"41":41,"46":46}],20:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('radar', { - scale: { - type: 'radialLinear' - }, - elements: { - line: { - tension: 0 // no bezier in radar - } - } -}); - -module.exports = function(Chart) { - - Chart.controllers.radar = Chart.DatasetController.extend({ - - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - linkScales: helpers.noop, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data; - var custom = line.custom || {}; - var dataset = me.getDataset(); - var lineElementOptions = me.chart.options.elements.line; - var scale = me.chart.scale; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { - dataset.lineTension = dataset.tension; - } - - helpers.extend(meta.dataset, { - // Utility - _datasetIndex: me.index, - _scale: scale, - // Data - _children: points, - _loop: true, - // Model - _model: { - // Appearance - tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, lineElementOptions.tension), - backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), - borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), - borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), - fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), - borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), - borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), - borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), - borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), - } - }); - - meta.dataset.pivot(); - - // Update Points - helpers.each(points, function(point, index) { - me.updateElement(point, index, reset); - }, me); - - // Update bezier control points - me.updateBezierControlPoints(); - }, - updateElement: function(point, index, reset) { - var me = this; - var custom = point.custom || {}; - var dataset = me.getDataset(); - var scale = me.chart.scale; - var pointElementOptions = me.chart.options.elements.point; - var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); - - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { - dataset.pointRadius = dataset.radius; - } - if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { - dataset.pointHitRadius = dataset.hitRadius; - } - - helpers.extend(point, { - // Utility - _datasetIndex: me.index, - _index: index, - _scale: scale, - - // Desired view properties - _model: { - x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales - y: reset ? scale.yCenter : pointPosition.y, - - // Appearance - tension: custom.tension ? custom.tension : helpers.valueOrDefault(dataset.lineTension, me.chart.options.elements.line.tension), - radius: custom.radius ? custom.radius : helpers.valueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius), - backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.valueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor), - borderColor: custom.borderColor ? custom.borderColor : helpers.valueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor), - borderWidth: custom.borderWidth ? custom.borderWidth : helpers.valueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth), - pointStyle: custom.pointStyle ? custom.pointStyle : helpers.valueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle), - rotation: custom.rotation ? custom.rotation : helpers.valueAtIndexOrDefault(dataset.pointRotation, index, pointElementOptions.rotation), - - // Tooltip - hitRadius: custom.hitRadius ? custom.hitRadius : helpers.valueAtIndexOrDefault(dataset.pointHitRadius, index, pointElementOptions.hitRadius) - } - }); - - point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - updateBezierControlPoints: function() { - var chartArea = this.chart.chartArea; - var meta = this.getMeta(); - - helpers.each(meta.data, function(point, index) { - var model = point._model; - var controlPoints = helpers.splineCurve( - helpers.previousItem(meta.data, index, true)._model, - model, - helpers.nextItem(meta.data, index, true)._model, - model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left); - model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top); - - model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left); - model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var custom = point.custom || {}; - var index = point._index; - var model = point._model; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.valueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); - model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); - model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.valueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); - }, - }); -}; - -},{"26":26,"41":41,"46":46}],21:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); - -defaults._set('scatter', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - id: 'x-axis-1', // need an ID so datasets can reference the scale - type: 'linear', // scatter should not use a category axis - position: 'bottom' - }], - yAxes: [{ - id: 'y-axis-1', - type: 'linear', - position: 'left' - }] - }, - - showLines: false, - - tooltips: { - callbacks: { - title: function() { - return ''; // doesn't make sense for scatter since data are formatted as a point - }, - label: function(item) { - return '(' + item.xLabel + ', ' + item.yLabel + ')'; - } - } - } -}); - -module.exports = function(Chart) { - - // Scatter charts use line controllers - Chart.controllers.scatter = Chart.controllers.line; - -}; - -},{"26":26}],22:[function(require,module,exports){ -'use strict'; - -var Element = require(27); - -var exports = module.exports = Element.extend({ - chart: null, // the animation associated chart instance - currentStep: 0, // the current animation step - numSteps: 60, // default number of steps - easing: '', // the easing to use for this animation - render: null, // render function used by the animation service - - onAnimationProgress: null, // user specified callback to fire on each step of the animation - onAnimationComplete: null, // user specified callback to fire when the animation finishes -}); - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.Animation instead - * @prop Chart.Animation#animationObject - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports.prototype, 'animationObject', { - get: function() { - return this; - } -}); - -/** - * Provided for backward compatibility, use Chart.Animation#chart instead - * @prop Chart.Animation#chartInstance - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports.prototype, 'chartInstance', { - get: function() { - return this.chart; - }, - set: function(value) { - this.chart = value; - } -}); - -},{"27":27}],23:[function(require,module,exports){ -/* global window: false */ -'use strict'; - -var defaults = require(26); -var helpers = require(46); - -defaults._set('global', { - animation: { - duration: 1000, - easing: 'easeOutQuart', - onProgress: helpers.noop, - onComplete: helpers.noop - } -}); - -module.exports = { - frameDuration: 17, - animations: [], - dropFrames: 0, - request: null, - - /** - * @param {Chart} chart - The chart to animate. - * @param {Chart.Animation} animation - The animation that we will animate. - * @param {Number} duration - The animation duration in ms. - * @param {Boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions - */ - addAnimation: function(chart, animation, duration, lazy) { - var animations = this.animations; - var i, ilen; - - animation.chart = chart; - - if (!lazy) { - chart.animating = true; - } - - for (i = 0, ilen = animations.length; i < ilen; ++i) { - if (animations[i].chart === chart) { - animations[i] = animation; - return; - } - } - - animations.push(animation); - - // If there are no animations queued, manually kickstart a digest, for lack of a better word - if (animations.length === 1) { - this.requestAnimationFrame(); - } - }, - - cancelAnimation: function(chart) { - var index = helpers.findIndex(this.animations, function(animation) { - return animation.chart === chart; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chart.animating = false; - } - }, - - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers.requestAnimFrame.call(window, function() { - me.request = null; - me.startDigest(); - }); - } - }, - - /** - * @private - */ - startDigest: function() { - var me = this; - var startTime = Date.now(); - var framesToDrop = 0; - - if (me.dropFrames > 1) { - framesToDrop = Math.floor(me.dropFrames); - me.dropFrames = me.dropFrames % 1; - } - - me.advance(1 + framesToDrop); - - var endTime = Date.now(); - - me.dropFrames += (endTime - startTime) / me.frameDuration; - - // Do we have more stuff to animate? - if (me.animations.length > 0) { - me.requestAnimationFrame(); - } - }, - - /** - * @private - */ - advance: function(count) { - var animations = this.animations; - var animation, chart; - var i = 0; - - while (i < animations.length) { - animation = animations[i]; - chart = animation.chart; - - animation.currentStep = (animation.currentStep || 0) + count; - animation.currentStep = Math.min(animation.currentStep, animation.numSteps); - - helpers.callback(animation.render, [chart, animation], chart); - helpers.callback(animation.onAnimationProgress, [animation], chart); - - if (animation.currentStep >= animation.numSteps) { - helpers.callback(animation.onAnimationComplete, [animation], chart); - chart.animating = false; - animations.splice(i, 1); - } else { - ++i; - } - } - } -}; - -},{"26":26,"46":46}],24:[function(require,module,exports){ -'use strict'; - -var Animation = require(22); -var animations = require(23); -var defaults = require(26); -var helpers = require(46); -var Interaction = require(29); -var layouts = require(31); -var platform = require(49); -var plugins = require(32); -var scaleService = require(34); -var Tooltip = require(36); - -module.exports = function(Chart) { - - // Create a dictionary of chart types, to allow for extension of existing types - Chart.types = {}; - - // Store a reference to each instance - allowing us to globally resize chart instances on window resize. - // Destroy method on the chart will remove the instance of the chart from this reference. - Chart.instances = {}; - - // Controllers available for dataset visualization eg. bar, line, slice, etc. - Chart.controllers = {}; - - /** - * Initializes the given config with global and chart default values. - */ - function initConfig(config) { - config = config || {}; - - // Do NOT use configMerge() for the data object because this method merges arrays - // and so would change references to labels and datasets, preventing data updates. - var data = config.data = config.data || {}; - data.datasets = data.datasets || []; - data.labels = data.labels || []; - - config.options = helpers.configMerge( - defaults.global, - defaults[config.type], - config.options || {}); - - return config; - } - - /** - * Updates the config of the chart - * @param chart {Chart} chart to update the options for - */ - function updateConfig(chart) { - var newOptions = chart.options; - - helpers.each(chart.scales, function(scale) { - layouts.removeBox(chart, scale); - }); - - newOptions = helpers.configMerge( - Chart.defaults.global, - Chart.defaults[chart.config.type], - newOptions); - - chart.options = chart.config.options = newOptions; - chart.ensureScalesHaveIDs(); - chart.buildOrUpdateScales(); - // Tooltip - chart.tooltip._options = newOptions.tooltips; - chart.tooltip.initialize(); - } - - function positionIsHorizontal(position) { - return position === 'top' || position === 'bottom'; - } - - helpers.extend(Chart.prototype, /** @lends Chart */ { - /** - * @private - */ - construct: function(item, config) { - var me = this; - - config = initConfig(config); - - var context = platform.acquireContext(item, config); - var canvas = context && context.canvas; - var height = canvas && canvas.height; - var width = canvas && canvas.width; - - me.id = helpers.uid(); - me.ctx = context; - me.canvas = canvas; - me.config = config; - me.width = width; - me.height = height; - me.aspectRatio = height ? width / height : null; - me.options = config.options; - me._bufferedRender = false; - - /** - * Provided for backward compatibility, Chart and Chart.Controller have been merged, - * the "instance" still need to be defined since it might be called from plugins. - * @prop Chart#chart - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ - me.chart = me; - me.controller = me; // chart.chart.controller #inception - - // Add the chart instance to the global namespace - Chart.instances[me.id] = me; - - // Define alias to the config data: `chart.data === chart.config.data` - Object.defineProperty(me, 'data', { - get: function() { - return me.config.data; - }, - set: function(value) { - me.config.data = value; - } - }); - - if (!context || !canvas) { - // The given item is not a compatible context2d element, let's return before finalizing - // the chart initialization but after setting basic chart / controller properties that - // can help to figure out that the chart is not valid (e.g chart.canvas !== null); - // https://github.com/chartjs/Chart.js/issues/2807 - console.error("Failed to create chart: can't acquire context from the given item"); - return; - } - - me.initialize(); - me.update(); - }, - - /** - * @private - */ - initialize: function() { - var me = this; - - // Before init plugin notification - plugins.notify(me, 'beforeInit'); - - helpers.retinaScale(me, me.options.devicePixelRatio); - - me.bindEvents(); - - if (me.options.responsive) { - // Initial resize before chart draws (must be silent to preserve initial animations). - me.resize(true); - } - - // Make sure scales have IDs and are built before we build any controllers. - me.ensureScalesHaveIDs(); - me.buildOrUpdateScales(); - me.initToolTip(); - - // After init plugin notification - plugins.notify(me, 'afterInit'); - - return me; - }, - - clear: function() { - helpers.canvas.clear(this); - return this; - }, - - stop: function() { - // Stops any current animation loop occurring - animations.cancelAnimation(this); - return this; - }, - - resize: function(silent) { - var me = this; - var options = me.options; - var canvas = me.canvas; - var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null; - - // the canvas render width and height will be casted to integers so make sure that - // the canvas display style uses the same integer values to avoid blurring effect. - - // Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed - var newWidth = Math.max(0, Math.floor(helpers.getMaximumWidth(canvas))); - var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas))); - - if (me.width === newWidth && me.height === newHeight) { - return; - } - - canvas.width = me.width = newWidth; - canvas.height = me.height = newHeight; - canvas.style.width = newWidth + 'px'; - canvas.style.height = newHeight + 'px'; - - helpers.retinaScale(me, options.devicePixelRatio); - - if (!silent) { - // Notify any plugins about the resize - var newSize = {width: newWidth, height: newHeight}; - plugins.notify(me, 'resize', [newSize]); - - // Notify of resize - if (me.options.onResize) { - me.options.onResize(me, newSize); - } - - me.stop(); - me.update({ - duration: me.options.responsiveAnimationDuration - }); - } - }, - - ensureScalesHaveIDs: function() { - var options = this.options; - var scalesOptions = options.scales || {}; - var scaleOptions = options.scale; - - helpers.each(scalesOptions.xAxes, function(xAxisOptions, index) { - xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index); - }); - - helpers.each(scalesOptions.yAxes, function(yAxisOptions, index) { - yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index); - }); - - if (scaleOptions) { - scaleOptions.id = scaleOptions.id || 'scale'; - } - }, - - /** - * Builds a map of scale ID to scale object for future lookup. - */ - buildOrUpdateScales: function() { - var me = this; - var options = me.options; - var scales = me.scales || {}; - var items = []; - var updated = Object.keys(scales).reduce(function(obj, id) { - obj[id] = false; - return obj; - }, {}); - - if (options.scales) { - items = items.concat( - (options.scales.xAxes || []).map(function(xAxisOptions) { - return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'}; - }), - (options.scales.yAxes || []).map(function(yAxisOptions) { - return {options: yAxisOptions, dtype: 'linear', dposition: 'left'}; - }) - ); - } - - if (options.scale) { - items.push({ - options: options.scale, - dtype: 'radialLinear', - isDefault: true, - dposition: 'chartArea' - }); - } - - helpers.each(items, function(item) { - var scaleOptions = item.options; - var id = scaleOptions.id; - var scaleType = helpers.valueOrDefault(scaleOptions.type, item.dtype); - - if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) { - scaleOptions.position = item.dposition; - } - - updated[id] = true; - var scale = null; - if (id in scales && scales[id].type === scaleType) { - scale = scales[id]; - scale.options = scaleOptions; - scale.ctx = me.ctx; - scale.chart = me; - } else { - var scaleClass = scaleService.getScaleConstructor(scaleType); - if (!scaleClass) { - return; - } - scale = new scaleClass({ - id: id, - type: scaleType, - options: scaleOptions, - ctx: me.ctx, - chart: me - }); - scales[scale.id] = scale; - } - - scale.mergeTicksOptions(); - - // TODO(SB): I think we should be able to remove this custom case (options.scale) - // and consider it as a regular scale part of the "scales"" map only! This would - // make the logic easier and remove some useless? custom code. - if (item.isDefault) { - me.scale = scale; - } - }); - // clear up discarded scales - helpers.each(updated, function(hasUpdated, id) { - if (!hasUpdated) { - delete scales[id]; - } - }); - - me.scales = scales; - - scaleService.addScalesToLayout(this); - }, - - buildOrUpdateControllers: function() { - var me = this; - var types = []; - var newControllers = []; - - helpers.each(me.data.datasets, function(dataset, datasetIndex) { - var meta = me.getDatasetMeta(datasetIndex); - var type = dataset.type || me.config.type; - - if (meta.type && meta.type !== type) { - me.destroyDatasetMeta(datasetIndex); - meta = me.getDatasetMeta(datasetIndex); - } - meta.type = type; - - types.push(meta.type); - - if (meta.controller) { - meta.controller.updateIndex(datasetIndex); - meta.controller.linkScales(); - } else { - var ControllerClass = Chart.controllers[meta.type]; - if (ControllerClass === undefined) { - throw new Error('"' + meta.type + '" is not a chart type.'); - } - - meta.controller = new ControllerClass(me, datasetIndex); - newControllers.push(meta.controller); - } - }, me); - - return newControllers; - }, - - /** - * Reset the elements of all datasets - * @private - */ - resetElements: function() { - var me = this; - helpers.each(me.data.datasets, function(dataset, datasetIndex) { - me.getDatasetMeta(datasetIndex).controller.reset(); - }, me); - }, - - /** - * Resets the chart back to it's state before the initial animation - */ - reset: function() { - this.resetElements(); - this.tooltip.initialize(); - }, - - update: function(config) { - var me = this; - - if (!config || typeof config !== 'object') { - // backwards compatibility - config = { - duration: config, - lazy: arguments[1] - }; - } - - updateConfig(me); - - // plugins options references might have change, let's invalidate the cache - // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 - plugins._invalidate(me); - - if (plugins.notify(me, 'beforeUpdate') === false) { - return; - } - - // In case the entire data object changed - me.tooltip._data = me.data; - - // Make sure dataset controllers are updated and new controllers are reset - var newControllers = me.buildOrUpdateControllers(); - - // Make sure all dataset controllers have correct meta data counts - helpers.each(me.data.datasets, function(dataset, datasetIndex) { - me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); - }, me); - - me.updateLayout(); - - // Can only reset the new controllers after the scales have been updated - if (me.options.animation && me.options.animation.duration) { - helpers.each(newControllers, function(controller) { - controller.reset(); - }); - } - - me.updateDatasets(); - - // Need to reset tooltip in case it is displayed with elements that are removed - // after update. - me.tooltip.initialize(); - - // Last active contains items that were previously in the tooltip. - // When we reset the tooltip, we need to clear it - me.lastActive = []; - - // Do this before render so that any plugins that need final scale updates can use it - plugins.notify(me, 'afterUpdate'); - - if (me._bufferedRender) { - me._bufferedRequest = { - duration: config.duration, - easing: config.easing, - lazy: config.lazy - }; - } else { - me.render(config); - } - }, - - /** - * Updates the chart layout unless a plugin returns `false` to the `beforeLayout` - * hook, in which case, plugins will not be called on `afterLayout`. - * @private - */ - updateLayout: function() { - var me = this; - - if (plugins.notify(me, 'beforeLayout') === false) { - return; - } - - layouts.update(this, this.width, this.height); - - /** - * Provided for backward compatibility, use `afterLayout` instead. - * @method IPlugin#afterScaleUpdate - * @deprecated since version 2.5.0 - * @todo remove at version 3 - * @private - */ - plugins.notify(me, 'afterScaleUpdate'); - plugins.notify(me, 'afterLayout'); - }, - - /** - * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate` - * hook, in which case, plugins will not be called on `afterDatasetsUpdate`. - * @private - */ - updateDatasets: function() { - var me = this; - - if (plugins.notify(me, 'beforeDatasetsUpdate') === false) { - return; - } - - for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { - me.updateDataset(i); - } - - plugins.notify(me, 'afterDatasetsUpdate'); - }, - - /** - * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate` - * hook, in which case, plugins will not be called on `afterDatasetUpdate`. - * @private - */ - updateDataset: function(index) { - var me = this; - var meta = me.getDatasetMeta(index); - var args = { - meta: meta, - index: index - }; - - if (plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) { - return; - } - - meta.controller.update(); - - plugins.notify(me, 'afterDatasetUpdate', [args]); - }, - - render: function(config) { - var me = this; - - if (!config || typeof config !== 'object') { - // backwards compatibility - config = { - duration: config, - lazy: arguments[1] - }; - } - - var duration = config.duration; - var lazy = config.lazy; - - if (plugins.notify(me, 'beforeRender') === false) { - return; - } - - var animationOptions = me.options.animation; - var onComplete = function(animation) { - plugins.notify(me, 'afterRender'); - helpers.callback(animationOptions && animationOptions.onComplete, [animation], me); - }; - - if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) { - var animation = new Animation({ - numSteps: (duration || animationOptions.duration) / 16.66, // 60 fps - easing: config.easing || animationOptions.easing, - - render: function(chart, animationObject) { - var easingFunction = helpers.easing.effects[animationObject.easing]; - var currentStep = animationObject.currentStep; - var stepDecimal = currentStep / animationObject.numSteps; - - chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep); - }, - - onAnimationProgress: animationOptions.onProgress, - onAnimationComplete: onComplete - }); - - animations.addAnimation(me, animation, duration, lazy); - } else { - me.draw(); - - // See https://github.com/chartjs/Chart.js/issues/3781 - onComplete(new Animation({numSteps: 0, chart: me})); - } - - return me; - }, - - draw: function(easingValue) { - var me = this; - - me.clear(); - - if (helpers.isNullOrUndef(easingValue)) { - easingValue = 1; - } - - me.transition(easingValue); - - if (me.width <= 0 || me.height <= 0) { - return; - } - - if (plugins.notify(me, 'beforeDraw', [easingValue]) === false) { - return; - } - - // Draw all the scales - helpers.each(me.boxes, function(box) { - box.draw(me.chartArea); - }, me); - - if (me.scale) { - me.scale.draw(); - } - - me.drawDatasets(easingValue); - me._drawTooltip(easingValue); - - plugins.notify(me, 'afterDraw', [easingValue]); - }, - - /** - * @private - */ - transition: function(easingValue) { - var me = this; - - for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) { - if (me.isDatasetVisible(i)) { - me.getDatasetMeta(i).controller.transition(easingValue); - } - } - - me.tooltip.transition(easingValue); - }, - - /** - * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw` - * hook, in which case, plugins will not be called on `afterDatasetsDraw`. - * @private - */ - drawDatasets: function(easingValue) { - var me = this; - - if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) { - return; - } - - // Draw datasets reversed to support proper line stacking - for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) { - if (me.isDatasetVisible(i)) { - me.drawDataset(i, easingValue); - } - } - - plugins.notify(me, 'afterDatasetsDraw', [easingValue]); - }, - - /** - * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw` - * hook, in which case, plugins will not be called on `afterDatasetDraw`. - * @private - */ - drawDataset: function(index, easingValue) { - var me = this; - var meta = me.getDatasetMeta(index); - var args = { - meta: meta, - index: index, - easingValue: easingValue - }; - - if (plugins.notify(me, 'beforeDatasetDraw', [args]) === false) { - return; - } - - meta.controller.draw(easingValue); - - plugins.notify(me, 'afterDatasetDraw', [args]); - }, - - /** - * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw` - * hook, in which case, plugins will not be called on `afterTooltipDraw`. - * @private - */ - _drawTooltip: function(easingValue) { - var me = this; - var tooltip = me.tooltip; - var args = { - tooltip: tooltip, - easingValue: easingValue - }; - - if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) { - return; - } - - tooltip.draw(); - - plugins.notify(me, 'afterTooltipDraw', [args]); - }, - - // Get the single element that was clicked on - // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw - getElementAtEvent: function(e) { - return Interaction.modes.single(this, e); - }, - - getElementsAtEvent: function(e) { - return Interaction.modes.label(this, e, {intersect: true}); - }, - - getElementsAtXAxis: function(e) { - return Interaction.modes['x-axis'](this, e, {intersect: true}); - }, - - getElementsAtEventForMode: function(e, mode, options) { - var method = Interaction.modes[mode]; - if (typeof method === 'function') { - return method(this, e, options); - } - - return []; - }, - - getDatasetAtEvent: function(e) { - return Interaction.modes.dataset(this, e, {intersect: true}); - }, - - getDatasetMeta: function(datasetIndex) { - var me = this; - var dataset = me.data.datasets[datasetIndex]; - if (!dataset._meta) { - dataset._meta = {}; - } - - var meta = dataset._meta[me.id]; - if (!meta) { - meta = dataset._meta[me.id] = { - type: null, - data: [], - dataset: null, - controller: null, - hidden: null, // See isDatasetVisible() comment - xAxisID: null, - yAxisID: null - }; - } - - return meta; - }, - - getVisibleDatasetCount: function() { - var count = 0; - for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { - if (this.isDatasetVisible(i)) { - count++; - } - } - return count; - }, - - isDatasetVisible: function(datasetIndex) { - var meta = this.getDatasetMeta(datasetIndex); - - // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false, - // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned. - return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden; - }, - - generateLegend: function() { - return this.options.legendCallback(this); - }, - - /** - * @private - */ - destroyDatasetMeta: function(datasetIndex) { - var id = this.id; - var dataset = this.data.datasets[datasetIndex]; - var meta = dataset._meta && dataset._meta[id]; - - if (meta) { - meta.controller.destroy(); - delete dataset._meta[id]; - } - }, - - destroy: function() { - var me = this; - var canvas = me.canvas; - var i, ilen; - - me.stop(); - - // dataset controllers need to cleanup associated data - for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { - me.destroyDatasetMeta(i); - } - - if (canvas) { - me.unbindEvents(); - helpers.canvas.clear(me); - platform.releaseContext(me.ctx); - me.canvas = null; - me.ctx = null; - } - - plugins.notify(me, 'destroy'); - - delete Chart.instances[me.id]; - }, - - toBase64Image: function() { - return this.canvas.toDataURL.apply(this.canvas, arguments); - }, - - initToolTip: function() { - var me = this; - me.tooltip = new Tooltip({ - _chart: me, - _chartInstance: me, // deprecated, backward compatibility - _data: me.data, - _options: me.options.tooltips - }, me); - }, - - /** - * @private - */ - bindEvents: function() { - var me = this; - var listeners = me._listeners = {}; - var listener = function() { - me.eventHandler.apply(me, arguments); - }; - - helpers.each(me.options.events, function(type) { - platform.addEventListener(me, type, listener); - listeners[type] = listener; - }); - - // Elements used to detect size change should not be injected for non responsive charts. - // See https://github.com/chartjs/Chart.js/issues/2210 - if (me.options.responsive) { - listener = function() { - me.resize(); - }; - - platform.addEventListener(me, 'resize', listener); - listeners.resize = listener; - } - }, - - /** - * @private - */ - unbindEvents: function() { - var me = this; - var listeners = me._listeners; - if (!listeners) { - return; - } - - delete me._listeners; - helpers.each(listeners, function(listener, type) { - platform.removeEventListener(me, type, listener); - }); - }, - - updateHoverStyle: function(elements, mode, enabled) { - var method = enabled ? 'setHoverStyle' : 'removeHoverStyle'; - var element, i, ilen; - - for (i = 0, ilen = elements.length; i < ilen; ++i) { - element = elements[i]; - if (element) { - this.getDatasetMeta(element._datasetIndex).controller[method](element); - } - } - }, - - /** - * @private - */ - eventHandler: function(e) { - var me = this; - var tooltip = me.tooltip; - - if (plugins.notify(me, 'beforeEvent', [e]) === false) { - return; - } - - // Buffer any update calls so that renders do not occur - me._bufferedRender = true; - me._bufferedRequest = null; - - var changed = me.handleEvent(e); - // for smooth tooltip animations issue #4989 - // the tooltip should be the source of change - // Animation check workaround: - // tooltip._start will be null when tooltip isn't animating - if (tooltip) { - changed = tooltip._start - ? tooltip.handleEvent(e) - : changed | tooltip.handleEvent(e); - } - - plugins.notify(me, 'afterEvent', [e]); - - var bufferedRequest = me._bufferedRequest; - if (bufferedRequest) { - // If we have an update that was triggered, we need to do a normal render - me.render(bufferedRequest); - } else if (changed && !me.animating) { - // If entering, leaving, or changing elements, animate the change via pivot - me.stop(); - - // We only need to render at this point. Updating will cause scales to be - // recomputed generating flicker & using more memory than necessary. - me.render({ - duration: me.options.hover.animationDuration, - lazy: true - }); - } - - me._bufferedRender = false; - me._bufferedRequest = null; - - return me; - }, - - /** - * Handle an event - * @private - * @param {IEvent} event the event to handle - * @return {Boolean} true if the chart needs to re-render - */ - handleEvent: function(e) { - var me = this; - var options = me.options || {}; - var hoverOptions = options.hover; - var changed = false; - - me.lastActive = me.lastActive || []; - - // Find Active Elements for hover and tooltips - if (e.type === 'mouseout') { - me.active = []; - } else { - me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions); - } - - // Invoke onHover hook - // Need to call with native event here to not break backwards compatibility - helpers.callback(options.onHover || options.hover.onHover, [e.native, me.active], me); - - if (e.type === 'mouseup' || e.type === 'click') { - if (options.onClick) { - // Use e.native here for backwards compatibility - options.onClick.call(me, e.native, me.active); - } - } - - // Remove styling for last active (even if it may still be active) - if (me.lastActive.length) { - me.updateHoverStyle(me.lastActive, hoverOptions.mode, false); - } - - // Built in hover styling - if (me.active.length && hoverOptions.mode) { - me.updateHoverStyle(me.active, hoverOptions.mode, true); - } - - changed = !helpers.arrayEquals(me.active, me.lastActive); - - // Remember Last Actives - me.lastActive = me.active; - - return changed; - } - }); - - /** - * Provided for backward compatibility, use Chart instead. - * @class Chart.Controller - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ - Chart.Controller = Chart; -}; - -},{"22":22,"23":23,"26":26,"29":29,"31":31,"32":32,"34":34,"36":36,"46":46,"49":49}],25:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); - -module.exports = function(Chart) { - - var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; - - /** - * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', - * 'unshift') and notify the listener AFTER the array has been altered. Listeners are - * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. - */ - function listenArrayEvents(array, listener) { - if (array._chartjs) { - array._chartjs.listeners.push(listener); - return; - } - - Object.defineProperty(array, '_chartjs', { - configurable: true, - enumerable: false, - value: { - listeners: [listener] - } - }); - - arrayEvents.forEach(function(key) { - var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); - var base = array[key]; - - Object.defineProperty(array, key, { - configurable: true, - enumerable: false, - value: function() { - var args = Array.prototype.slice.call(arguments); - var res = base.apply(this, args); - - helpers.each(array._chartjs.listeners, function(object) { - if (typeof object[method] === 'function') { - object[method].apply(object, args); - } - }); - - return res; - } - }); - }); - } - - /** - * Removes the given array event listener and cleanup extra attached properties (such as - * the _chartjs stub and overridden methods) if array doesn't have any more listeners. - */ - function unlistenArrayEvents(array, listener) { - var stub = array._chartjs; - if (!stub) { - return; - } - - var listeners = stub.listeners; - var index = listeners.indexOf(listener); - if (index !== -1) { - listeners.splice(index, 1); - } - - if (listeners.length > 0) { - return; - } - - arrayEvents.forEach(function(key) { - delete array[key]; - }); - - delete array._chartjs; - } - - // Base class for all dataset controllers (line, bar, etc) - Chart.DatasetController = function(chart, datasetIndex) { - this.initialize(chart, datasetIndex); - }; - - helpers.extend(Chart.DatasetController.prototype, { - - /** - * Element type used to generate a meta dataset (e.g. Chart.element.Line). - * @type {Chart.core.element} - */ - datasetElementType: null, - - /** - * Element type used to generate a meta data (e.g. Chart.element.Point). - * @type {Chart.core.element} - */ - dataElementType: null, - - initialize: function(chart, datasetIndex) { - var me = this; - me.chart = chart; - me.index = datasetIndex; - me.linkScales(); - me.addElements(); - }, - - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - var me = this; - var meta = me.getMeta(); - var dataset = me.getDataset(); - - if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) { - meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id; - } - if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) { - meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getMeta: function() { - return this.chart.getDatasetMeta(this.index); - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - - reset: function() { - this.update(true); - }, - - /** - * @private - */ - destroy: function() { - if (this._data) { - unlistenArrayEvents(this._data, this); - } - }, - - createMetaDataset: function() { - var me = this; - var type = me.datasetElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index - }); - }, - - createMetaData: function(index) { - var me = this; - var type = me.dataElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index, - _index: index - }); - }, - - addElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data || []; - var metaData = meta.data; - var i, ilen; - - for (i = 0, ilen = data.length; i < ilen; ++i) { - metaData[i] = metaData[i] || me.createMetaData(i); - } - - meta.dataset = meta.dataset || me.createMetaDataset(); - }, - - addElementAndReset: function(index) { - var element = this.createMetaData(index); - this.getMeta().data.splice(index, 0, element); - this.updateElement(element, index, true); - }, - - buildOrUpdateElements: function() { - var me = this; - var dataset = me.getDataset(); - var data = dataset.data || (dataset.data = []); - - // In order to correctly handle data addition/deletion animation (an thus simulate - // real-time charts), we need to monitor these data modifications and synchronize - // the internal meta data accordingly. - if (me._data !== data) { - if (me._data) { - // This case happens when the user replaced the data array instance. - unlistenArrayEvents(me._data, me); - } - - listenArrayEvents(data, me); - me._data = data; - } - - // Re-sync meta data in case the user replaced the data array or if we missed - // any updates and so make sure that we handle number of datapoints changing. - me.resyncElements(); - }, - - update: helpers.noop, - - transition: function(easingValue) { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - for (; i < ilen; ++i) { - elements[i].transition(easingValue); - } - - if (meta.dataset) { - meta.dataset.transition(easingValue); - } - }, - - draw: function() { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - if (meta.dataset) { - meta.dataset.draw(); - } - - for (; i < ilen; ++i) { - elements[i].draw(); - } - }, - - removeHoverStyle: function(element) { - helpers.merge(element._model, element.$previousStyle || {}); - delete element.$previousStyle; - }, - - setHoverStyle: function(element) { - var dataset = this.chart.data.datasets[element._datasetIndex]; - var index = element._index; - var custom = element.custom || {}; - var valueOrDefault = helpers.valueAtIndexOrDefault; - var getHoverColor = helpers.getHoverColor; - var model = element._model; - - element.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth - }; - - model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor)); - model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor)); - model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); - }, - - /** - * @private - */ - resyncElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data; - var numMeta = meta.data.length; - var numData = data.length; - - if (numData < numMeta) { - meta.data.splice(numData, numMeta - numData); - } else if (numData > numMeta) { - me.insertElements(numMeta, numData - numMeta); - } - }, - - /** - * @private - */ - insertElements: function(start, count) { - for (var i = 0; i < count; ++i) { - this.addElementAndReset(start + i); - } - }, - - /** - * @private - */ - onDataPush: function() { - this.insertElements(this.getDataset().data.length - 1, arguments.length); - }, - - /** - * @private - */ - onDataPop: function() { - this.getMeta().data.pop(); - }, - - /** - * @private - */ - onDataShift: function() { - this.getMeta().data.shift(); - }, - - /** - * @private - */ - onDataSplice: function(start, count) { - this.getMeta().data.splice(start, count); - this.insertElements(start, arguments.length - 2); - }, - - /** - * @private - */ - onDataUnshift: function() { - this.insertElements(0, arguments.length); - } - }); - - Chart.DatasetController.extend = helpers.inherits; -}; - -},{"46":46}],26:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); - -module.exports = { - /** - * @private - */ - _set: function(scope, values) { - return helpers.merge(this[scope] || (this[scope] = {}), values); - } -}; - -},{"46":46}],27:[function(require,module,exports){ -'use strict'; - -var color = require(2); -var helpers = require(46); - -function interpolate(start, view, model, ease) { - var keys = Object.keys(model); - var i, ilen, key, actual, origin, target, type, c0, c1; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - - target = model[key]; - - // if a value is added to the model after pivot() has been called, the view - // doesn't contain it, so let's initialize the view to the target value. - if (!view.hasOwnProperty(key)) { - view[key] = target; - } - - actual = view[key]; - - if (actual === target || key[0] === '_') { - continue; - } - - if (!start.hasOwnProperty(key)) { - start[key] = actual; - } - - origin = start[key]; - - type = typeof target; - - if (type === typeof origin) { - if (type === 'string') { - c0 = color(origin); - if (c0.valid) { - c1 = color(target); - if (c1.valid) { - view[key] = c1.mix(c0, ease).rgbString(); - continue; - } - } - } else if (type === 'number' && isFinite(origin) && isFinite(target)) { - view[key] = origin + (target - origin) * ease; - continue; - } - } - - view[key] = target; - } -} - -var Element = function(configuration) { - helpers.extend(this, configuration); - this.initialize.apply(this, arguments); -}; - -helpers.extend(Element.prototype, { - - initialize: function() { - this.hidden = false; - }, - - pivot: function() { - var me = this; - if (!me._view) { - me._view = helpers.clone(me._model); - } - me._start = {}; - return me; - }, - - transition: function(ease) { - var me = this; - var model = me._model; - var start = me._start; - var view = me._view; - - // No animation -> No Transition - if (!model || ease === 1) { - me._view = model; - me._start = null; - return me; - } - - if (!view) { - view = me._view = {}; - } - - if (!start) { - start = me._start = {}; - } - - interpolate(start, view, model, ease); - - return me; - }, - - tooltipPosition: function() { - return { - x: this._model.x, - y: this._model.y - }; - }, - - hasValue: function() { - return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y); - } -}); - -Element.extend = helpers.inherits; - -module.exports = Element; - -},{"2":2,"46":46}],28:[function(require,module,exports){ -/* global window: false */ -/* global document: false */ -'use strict'; - -var color = require(2); -var defaults = require(26); -var helpers = require(46); -var scaleService = require(34); - -module.exports = function() { - - // -- Basic js utility methods - - helpers.configMerge = function(/* objects ... */) { - return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), { - merger: function(key, target, source, options) { - var tval = target[key] || {}; - var sval = source[key]; - - if (key === 'scales') { - // scale config merging is complex. Add our own function here for that - target[key] = helpers.scaleMerge(tval, sval); - } else if (key === 'scale') { - // used in polar area & radar charts since there is only one scale - target[key] = helpers.merge(tval, [scaleService.getScaleDefaults(sval.type), sval]); - } else { - helpers._merger(key, target, source, options); - } - } - }); - }; - - helpers.scaleMerge = function(/* objects ... */) { - return helpers.merge(helpers.clone(arguments[0]), [].slice.call(arguments, 1), { - merger: function(key, target, source, options) { - if (key === 'xAxes' || key === 'yAxes') { - var slen = source[key].length; - var i, type, scale; - - if (!target[key]) { - target[key] = []; - } - - for (i = 0; i < slen; ++i) { - scale = source[key][i]; - type = helpers.valueOrDefault(scale.type, key === 'xAxes' ? 'category' : 'linear'); - - if (i >= target[key].length) { - target[key].push({}); - } - - if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) { - // new/untyped scale or type changed: let's apply the new defaults - // then merge source scale to correctly overwrite the defaults. - helpers.merge(target[key][i], [scaleService.getScaleDefaults(type), scale]); - } else { - // scales type are the same - helpers.merge(target[key][i], scale); - } - } - } else { - helpers._merger(key, target, source, options); - } - } - }); - }; - - helpers.where = function(collection, filterCallback) { - if (helpers.isArray(collection) && Array.prototype.filter) { - return collection.filter(filterCallback); - } - var filtered = []; - - helpers.each(collection, function(item) { - if (filterCallback(item)) { - filtered.push(item); - } - }); - - return filtered; - }; - helpers.findIndex = Array.prototype.findIndex ? - function(array, callback, scope) { - return array.findIndex(callback, scope); - } : - function(array, callback, scope) { - scope = scope === undefined ? array : scope; - for (var i = 0, ilen = array.length; i < ilen; ++i) { - if (callback.call(scope, array[i], i, array)) { - return i; - } - } - return -1; - }; - helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to start of the array - if (helpers.isNullOrUndef(startIndex)) { - startIndex = -1; - } - for (var i = startIndex + 1; i < arrayToSearch.length; i++) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to end of the array - if (helpers.isNullOrUndef(startIndex)) { - startIndex = arrayToSearch.length; - } - for (var i = startIndex - 1; i >= 0; i--) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - - // -- Math methods - helpers.isNumber = function(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - }; - helpers.almostEquals = function(x, y, epsilon) { - return Math.abs(x - y) < epsilon; - }; - helpers.almostWhole = function(x, epsilon) { - var rounded = Math.round(x); - return (((rounded - epsilon) < x) && ((rounded + epsilon) > x)); - }; - helpers.max = function(array) { - return array.reduce(function(max, value) { - if (!isNaN(value)) { - return Math.max(max, value); - } - return max; - }, Number.NEGATIVE_INFINITY); - }; - helpers.min = function(array) { - return array.reduce(function(min, value) { - if (!isNaN(value)) { - return Math.min(min, value); - } - return min; - }, Number.POSITIVE_INFINITY); - }; - helpers.sign = Math.sign ? - function(x) { - return Math.sign(x); - } : - function(x) { - x = +x; // convert to a number - if (x === 0 || isNaN(x)) { - return x; - } - return x > 0 ? 1 : -1; - }; - helpers.log10 = Math.log10 ? - function(x) { - return Math.log10(x); - } : - function(x) { - var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. - // Check for whole powers of 10, - // which due to floating point rounding error should be corrected. - var powerOf10 = Math.round(exponent); - var isPowerOf10 = x === Math.pow(10, powerOf10); - - return isPowerOf10 ? powerOf10 : exponent; - }; - helpers.toRadians = function(degrees) { - return degrees * (Math.PI / 180); - }; - helpers.toDegrees = function(radians) { - return radians * (180 / Math.PI); - }; - // Gets the angle from vertical upright to the point about a centre. - helpers.getAngleFromPoint = function(centrePoint, anglePoint) { - var distanceFromXCenter = anglePoint.x - centrePoint.x; - var distanceFromYCenter = anglePoint.y - centrePoint.y; - var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); - - var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); - - if (angle < (-0.5 * Math.PI)) { - angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2] - } - - return { - angle: angle, - distance: radialDistanceFromCenter - }; - }; - helpers.distanceBetweenPoints = function(pt1, pt2) { - return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); - }; - helpers.aliasPixel = function(pixelWidth) { - return (pixelWidth % 2 === 0) ? 0 : 0.5; - }; - helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) { - // Props to Rob Spencer at scaled innovation for his post on splining between points - // http://scaledinnovation.com/analytics/splines/aboutSplines.html - - // This function must also respect "skipped" points - - var previous = firstPoint.skip ? middlePoint : firstPoint; - var current = middlePoint; - var next = afterPoint.skip ? middlePoint : afterPoint; - - var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2)); - var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2)); - - var s01 = d01 / (d01 + d12); - var s12 = d12 / (d01 + d12); - - // If all points are the same, s01 & s02 will be inf - s01 = isNaN(s01) ? 0 : s01; - s12 = isNaN(s12) ? 0 : s12; - - var fa = t * s01; // scaling factor for triangle Ta - var fb = t * s12; - - return { - previous: { - x: current.x - fa * (next.x - previous.x), - y: current.y - fa * (next.y - previous.y) - }, - next: { - x: current.x + fb * (next.x - previous.x), - y: current.y + fb * (next.y - previous.y) - } - }; - }; - helpers.EPSILON = Number.EPSILON || 1e-14; - helpers.splineCurveMonotone = function(points) { - // This function calculates BĂ©zier control points in a similar way than |splineCurve|, - // but preserves monotonicity of the provided data and ensures no local extremums are added - // between the dataset discrete points due to the interpolation. - // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation - - var pointsWithTangents = (points || []).map(function(point) { - return { - model: point._model, - deltaK: 0, - mK: 0 - }; - }); - - // Calculate slopes (deltaK) and initialize tangents (mK) - var pointsLen = pointsWithTangents.length; - var i, pointBefore, pointCurrent, pointAfter; - for (i = 0; i < pointsLen; ++i) { - pointCurrent = pointsWithTangents[i]; - if (pointCurrent.model.skip) { - continue; - } - - pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; - pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; - if (pointAfter && !pointAfter.model.skip) { - var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x); - - // In the case of two points that appear at the same x pixel, slopeDeltaX is 0 - pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0; - } - - if (!pointBefore || pointBefore.model.skip) { - pointCurrent.mK = pointCurrent.deltaK; - } else if (!pointAfter || pointAfter.model.skip) { - pointCurrent.mK = pointBefore.deltaK; - } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) { - pointCurrent.mK = 0; - } else { - pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2; - } - } - - // Adjust tangents to ensure monotonic properties - var alphaK, betaK, tauK, squaredMagnitude; - for (i = 0; i < pointsLen - 1; ++i) { - pointCurrent = pointsWithTangents[i]; - pointAfter = pointsWithTangents[i + 1]; - if (pointCurrent.model.skip || pointAfter.model.skip) { - continue; - } - - if (helpers.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) { - pointCurrent.mK = pointAfter.mK = 0; - continue; - } - - alphaK = pointCurrent.mK / pointCurrent.deltaK; - betaK = pointAfter.mK / pointCurrent.deltaK; - squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2); - if (squaredMagnitude <= 9) { - continue; - } - - tauK = 3 / Math.sqrt(squaredMagnitude); - pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK; - pointAfter.mK = betaK * tauK * pointCurrent.deltaK; - } - - // Compute control points - var deltaX; - for (i = 0; i < pointsLen; ++i) { - pointCurrent = pointsWithTangents[i]; - if (pointCurrent.model.skip) { - continue; - } - - pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; - pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; - if (pointBefore && !pointBefore.model.skip) { - deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3; - pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX; - pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK; - } - if (pointAfter && !pointAfter.model.skip) { - deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3; - pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX; - pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK; - } - } - }; - helpers.nextItem = function(collection, index, loop) { - if (loop) { - return index >= collection.length - 1 ? collection[0] : collection[index + 1]; - } - return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1]; - }; - helpers.previousItem = function(collection, index, loop) { - if (loop) { - return index <= 0 ? collection[collection.length - 1] : collection[index - 1]; - } - return index <= 0 ? collection[0] : collection[index - 1]; - }; - // Implementation of the nice number algorithm used in determining where axis labels will go - helpers.niceNum = function(range, round) { - var exponent = Math.floor(helpers.log10(range)); - var fraction = range / Math.pow(10, exponent); - var niceFraction; - - if (round) { - if (fraction < 1.5) { - niceFraction = 1; - } else if (fraction < 3) { - niceFraction = 2; - } else if (fraction < 7) { - niceFraction = 5; - } else { - niceFraction = 10; - } - } else if (fraction <= 1.0) { - niceFraction = 1; - } else if (fraction <= 2) { - niceFraction = 2; - } else if (fraction <= 5) { - niceFraction = 5; - } else { - niceFraction = 10; - } - - return niceFraction * Math.pow(10, exponent); - }; - // Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ - helpers.requestAnimFrame = (function() { - if (typeof window === 'undefined') { - return function(callback) { - callback(); - }; - } - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(callback) { - return window.setTimeout(callback, 1000 / 60); - }; - }()); - // -- DOM methods - helpers.getRelativePosition = function(evt, chart) { - var mouseX, mouseY; - var e = evt.originalEvent || evt; - var canvas = evt.target || evt.srcElement; - var boundingRect = canvas.getBoundingClientRect(); - - var touches = e.touches; - if (touches && touches.length > 0) { - mouseX = touches[0].clientX; - mouseY = touches[0].clientY; - - } else { - mouseX = e.clientX; - mouseY = e.clientY; - } - - // Scale mouse coordinates into canvas coordinates - // by following the pattern laid out by 'jerryj' in the comments of - // http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/ - var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left')); - var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top')); - var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right')); - var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom')); - var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight; - var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom; - - // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However - // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here - mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio); - mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio); - - return { - x: mouseX, - y: mouseY - }; - - }; - - // Private helper function to convert max-width/max-height values that may be percentages into a number - function parseMaxStyle(styleValue, node, parentProperty) { - var valueInPixels; - if (typeof styleValue === 'string') { - valueInPixels = parseInt(styleValue, 10); - - if (styleValue.indexOf('%') !== -1) { - // percentage * size in dimension - valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; - } - } else { - valueInPixels = styleValue; - } - - return valueInPixels; - } - - /** - * Returns if the given value contains an effective constraint. - * @private - */ - function isConstrainedValue(value) { - return value !== undefined && value !== null && value !== 'none'; - } - - // Private helper to get a constraint dimension - // @param domNode : the node to check the constraint on - // @param maxStyle : the style that defines the maximum for the direction we are using (maxWidth / maxHeight) - // @param percentageProperty : property of parent to use when calculating width as a percentage - // @see http://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser - function getConstraintDimension(domNode, maxStyle, percentageProperty) { - var view = document.defaultView; - var parentNode = helpers._getParentNode(domNode); - var constrainedNode = view.getComputedStyle(domNode)[maxStyle]; - var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle]; - var hasCNode = isConstrainedValue(constrainedNode); - var hasCContainer = isConstrainedValue(constrainedContainer); - var infinity = Number.POSITIVE_INFINITY; - - if (hasCNode || hasCContainer) { - return Math.min( - hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity, - hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity); - } - - return 'none'; - } - // returns Number or undefined if no constraint - helpers.getConstraintWidth = function(domNode) { - return getConstraintDimension(domNode, 'max-width', 'clientWidth'); - }; - // returns Number or undefined if no constraint - helpers.getConstraintHeight = function(domNode) { - return getConstraintDimension(domNode, 'max-height', 'clientHeight'); - }; - /** - * @private - */ - helpers._calculatePadding = function(container, padding, parentDimension) { - padding = helpers.getStyle(container, padding); - - return padding.indexOf('%') > -1 ? parentDimension / parseInt(padding, 10) : parseInt(padding, 10); - }; - /** - * @private - */ - helpers._getParentNode = function(domNode) { - var parent = domNode.parentNode; - if (parent && parent.host) { - parent = parent.host; - } - return parent; - }; - helpers.getMaximumWidth = function(domNode) { - var container = helpers._getParentNode(domNode); - if (!container) { - return domNode.clientWidth; - } - - var clientWidth = container.clientWidth; - var paddingLeft = helpers._calculatePadding(container, 'padding-left', clientWidth); - var paddingRight = helpers._calculatePadding(container, 'padding-right', clientWidth); - - var w = clientWidth - paddingLeft - paddingRight; - var cw = helpers.getConstraintWidth(domNode); - return isNaN(cw) ? w : Math.min(w, cw); - }; - helpers.getMaximumHeight = function(domNode) { - var container = helpers._getParentNode(domNode); - if (!container) { - return domNode.clientHeight; - } - - var clientHeight = container.clientHeight; - var paddingTop = helpers._calculatePadding(container, 'padding-top', clientHeight); - var paddingBottom = helpers._calculatePadding(container, 'padding-bottom', clientHeight); - - var h = clientHeight - paddingTop - paddingBottom; - var ch = helpers.getConstraintHeight(domNode); - return isNaN(ch) ? h : Math.min(h, ch); - }; - helpers.getStyle = function(el, property) { - return el.currentStyle ? - el.currentStyle[property] : - document.defaultView.getComputedStyle(el, null).getPropertyValue(property); - }; - helpers.retinaScale = function(chart, forceRatio) { - var pixelRatio = chart.currentDevicePixelRatio = forceRatio || (typeof window !== 'undefined' && window.devicePixelRatio) || 1; - if (pixelRatio === 1) { - return; - } - - var canvas = chart.canvas; - var height = chart.height; - var width = chart.width; - - canvas.height = height * pixelRatio; - canvas.width = width * pixelRatio; - chart.ctx.scale(pixelRatio, pixelRatio); - - // If no style has been set on the canvas, the render size is used as display size, - // making the chart visually bigger, so let's enforce it to the "correct" values. - // See https://github.com/chartjs/Chart.js/issues/3575 - if (!canvas.style.height && !canvas.style.width) { - canvas.style.height = height + 'px'; - canvas.style.width = width + 'px'; - } - }; - // -- Canvas methods - helpers.fontString = function(pixelSize, fontStyle, fontFamily) { - return fontStyle + ' ' + pixelSize + 'px ' + fontFamily; - }; - helpers.longestText = function(ctx, font, arrayOfThings, cache) { - cache = cache || {}; - var data = cache.data = cache.data || {}; - var gc = cache.garbageCollect = cache.garbageCollect || []; - - if (cache.font !== font) { - data = cache.data = {}; - gc = cache.garbageCollect = []; - cache.font = font; - } - - ctx.font = font; - var longest = 0; - helpers.each(arrayOfThings, function(thing) { - // Undefined strings and arrays should not be measured - if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) { - longest = helpers.measureText(ctx, data, gc, longest, thing); - } else if (helpers.isArray(thing)) { - // if it is an array lets measure each element - // to do maybe simplify this function a bit so we can do this more recursively? - helpers.each(thing, function(nestedThing) { - // Undefined strings and arrays should not be measured - if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) { - longest = helpers.measureText(ctx, data, gc, longest, nestedThing); - } - }); - } - }); - - var gcLen = gc.length / 2; - if (gcLen > arrayOfThings.length) { - for (var i = 0; i < gcLen; i++) { - delete data[gc[i]]; - } - gc.splice(0, gcLen); - } - return longest; - }; - helpers.measureText = function(ctx, data, gc, longest, string) { - var textWidth = data[string]; - if (!textWidth) { - textWidth = data[string] = ctx.measureText(string).width; - gc.push(string); - } - if (textWidth > longest) { - longest = textWidth; - } - return longest; - }; - helpers.numberOfLabelLines = function(arrayOfThings) { - var numberOfLines = 1; - helpers.each(arrayOfThings, function(thing) { - if (helpers.isArray(thing)) { - if (thing.length > numberOfLines) { - numberOfLines = thing.length; - } - } - }); - return numberOfLines; - }; - - helpers.color = !color ? - function(value) { - console.error('Color.js not found!'); - return value; - } : - function(value) { - /* global CanvasGradient */ - if (value instanceof CanvasGradient) { - value = defaults.global.defaultColor; - } - - return color(value); - }; - - helpers.getHoverColor = function(colorValue) { - /* global CanvasPattern */ - return (colorValue instanceof CanvasPattern) ? - colorValue : - helpers.color(colorValue).saturate(0.5).darken(0.1).rgbString(); - }; -}; - -},{"2":2,"26":26,"34":34,"46":46}],29:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); - -/** - * Helper function to get relative position for an event - * @param {Event|IEvent} event - The event to get the position for - * @param {Chart} chart - The chart - * @returns {Point} the event position - */ -function getRelativePosition(e, chart) { - if (e.native) { - return { - x: e.x, - y: e.y - }; - } - - return helpers.getRelativePosition(e, chart); -} - -/** - * Helper function to traverse all of the visible elements in the chart - * @param chart {chart} the chart - * @param handler {Function} the callback to execute for each visible item - */ -function parseVisibleItems(chart, handler) { - var datasets = chart.data.datasets; - var meta, i, j, ilen, jlen; - - for (i = 0, ilen = datasets.length; i < ilen; ++i) { - if (!chart.isDatasetVisible(i)) { - continue; - } - - meta = chart.getDatasetMeta(i); - for (j = 0, jlen = meta.data.length; j < jlen; ++j) { - var element = meta.data[j]; - if (!element._view.skip) { - handler(element); - } - } - } -} - -/** - * Helper function to get the items that intersect the event position - * @param items {ChartElement[]} elements to filter - * @param position {Point} the point to be nearest to - * @return {ChartElement[]} the nearest items - */ -function getIntersectItems(chart, position) { - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - } - }); - - return elements; -} - -/** - * Helper function to get the items nearest to the event position considering all visible items in teh chart - * @param chart {Chart} the chart to look at elements from - * @param position {Point} the point to be nearest to - * @param intersect {Boolean} if true, only consider items that intersect the position - * @param distanceMetric {Function} function to provide the distance between points - * @return {ChartElement[]} the nearest items - */ -function getNearestItems(chart, position, intersect, distanceMetric) { - var minDistance = Number.POSITIVE_INFINITY; - var nearestItems = []; - - parseVisibleItems(chart, function(element) { - if (intersect && !element.inRange(position.x, position.y)) { - return; - } - - var center = element.getCenterPoint(); - var distance = distanceMetric(position, center); - - if (distance < minDistance) { - nearestItems = [element]; - minDistance = distance; - } else if (distance === minDistance) { - // Can have multiple items at the same distance in which case we sort by size - nearestItems.push(element); - } - }); - - return nearestItems; -} - -/** - * Get a distance metric function for two points based on the - * axis mode setting - * @param {String} axis the axis mode. x|y|xy - */ -function getDistanceMetricForAxis(axis) { - var useX = axis.indexOf('x') !== -1; - var useY = axis.indexOf('y') !== -1; - - return function(pt1, pt2) { - var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; - var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; - return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); - }; -} - -function indexMode(chart, e, options) { - var position = getRelativePosition(e, chart); - // Default axis for index mode is 'x' to match old behaviour - options.axis = options.axis || 'x'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - var elements = []; - - if (!items.length) { - return []; - } - - chart.data.datasets.forEach(function(dataset, datasetIndex) { - if (chart.isDatasetVisible(datasetIndex)) { - var meta = chart.getDatasetMeta(datasetIndex); - var element = meta.data[items[0]._index]; - - // don't count items that are skipped (null data) - if (element && !element._view.skip) { - elements.push(element); - } - } - }); - - return elements; -} - -/** - * @interface IInteractionOptions - */ -/** - * If true, only consider items that intersect the point - * @name IInterfaceOptions#boolean - * @type Boolean - */ - -/** - * Contains interaction related functions - * @namespace Chart.Interaction - */ -module.exports = { - // Helper function for different modes - modes: { - single: function(chart, e) { - var position = getRelativePosition(e, chart); - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - return elements; - } - }); - - return elements.slice(0, 1); - }, - - /** - * @function Chart.Interaction.modes.label - * @deprecated since version 2.4.0 - * @todo remove at version 3 - * @private - */ - label: indexMode, - - /** - * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item - * @function Chart.Interaction.modes.index - * @since v2.4.0 - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @param options {IInteractionOptions} options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - index: indexMode, - - /** - * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect is false, we find the nearest item and return the items in that dataset - * @function Chart.Interaction.modes.dataset - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @param options {IInteractionOptions} options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - dataset: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - - if (items.length > 0) { - items = chart.getDatasetMeta(items[0]._datasetIndex).data; - } - - return items; - }, - - /** - * @function Chart.Interaction.modes.x-axis - * @deprecated since version 2.4.0. Use index mode and intersect == true - * @todo remove at version 3 - * @private - */ - 'x-axis': function(chart, e) { - return indexMode(chart, e, {intersect: false}); - }, - - /** - * Point mode returns all elements that hit test based on the event position - * of the event - * @function Chart.Interaction.modes.intersect - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - point: function(chart, e) { - var position = getRelativePosition(e, chart); - return getIntersectItems(chart, position); - }, - - /** - * nearest mode returns the element closest to the point - * @function Chart.Interaction.modes.intersect - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @param options {IInteractionOptions} options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - nearest: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var nearestItems = getNearestItems(chart, position, options.intersect, distanceMetric); - - // We have multiple items at the same distance from the event. Now sort by smallest - if (nearestItems.length > 1) { - nearestItems.sort(function(a, b) { - var sizeA = a.getArea(); - var sizeB = b.getArea(); - var ret = sizeA - sizeB; - - if (ret === 0) { - // if equal sort by dataset index - ret = a._datasetIndex - b._datasetIndex; - } - - return ret; - }); - } - - // Return only 1 item - return nearestItems.slice(0, 1); - }, - - /** - * x mode returns the elements that hit-test at the current x coordinate - * @function Chart.Interaction.modes.x - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @param options {IInteractionOptions} options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - x: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inXRange(position.x)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - }, - - /** - * y mode returns the elements that hit-test at the current y coordinate - * @function Chart.Interaction.modes.y - * @param chart {chart} the chart we are returning items from - * @param e {Event} the event we are find things at - * @param options {IInteractionOptions} options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - y: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inYRange(position.y)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - } - } -}; - -},{"46":46}],30:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); - -defaults._set('global', { - responsive: true, - responsiveAnimationDuration: 0, - maintainAspectRatio: true, - events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'], - hover: { - onHover: null, - mode: 'nearest', - intersect: true, - animationDuration: 400 - }, - onClick: null, - defaultColor: 'rgba(0,0,0,0.1)', - defaultFontColor: '#666', - defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", - defaultFontSize: 12, - defaultFontStyle: 'normal', - showLines: true, - - // Element defaults defined in element extensions - elements: {}, - - // Layout options such as padding - layout: { - padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - } -}); - -module.exports = function() { - - // Occupy the global variable of Chart, and create a simple base class - var Chart = function(item, config) { - this.construct(item, config); - return this; - }; - - Chart.Chart = Chart; - - return Chart; -}; - -},{"26":26}],31:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); - -function filterByPosition(array, position) { - return helpers.where(array, function(v) { - return v.position === position; - }); -} - -function sortByWeight(array, reverse) { - array.forEach(function(v, i) { - v._tmpIndex_ = i; - return v; - }); - array.sort(function(a, b) { - var v0 = reverse ? b : a; - var v1 = reverse ? a : b; - return v0.weight === v1.weight ? - v0._tmpIndex_ - v1._tmpIndex_ : - v0.weight - v1.weight; - }); - array.forEach(function(v) { - delete v._tmpIndex_; - }); -} - -/** - * @interface ILayoutItem - * @prop {String} position - The position of the item in the chart layout. Possible values are - * 'left', 'top', 'right', 'bottom', and 'chartArea' - * @prop {Number} weight - The weight used to sort the item. Higher weights are further away from the chart area - * @prop {Boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down - * @prop {Function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) - * @prop {Function} update - Takes two parameters: width and height. Returns size of item - * @prop {Function} getPadding - Returns an object with padding on the edges - * @prop {Number} width - Width of item. Must be valid after update() - * @prop {Number} height - Height of item. Must be valid after update() - * @prop {Number} left - Left edge of the item. Set by layout system and cannot be used in update - * @prop {Number} top - Top edge of the item. Set by layout system and cannot be used in update - * @prop {Number} right - Right edge of the item. Set by layout system and cannot be used in update - * @prop {Number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update - */ - -// The layout service is very self explanatory. It's responsible for the layout within a chart. -// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need -// It is this service's responsibility of carrying out that layout. -module.exports = { - defaults: {}, - - /** - * Register a box to a chart. - * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. - * @param {Chart} chart - the chart to use - * @param {ILayoutItem} item - the item to add to be layed out - */ - addBox: function(chart, item) { - if (!chart.boxes) { - chart.boxes = []; - } - - // initialize item with default values - item.fullWidth = item.fullWidth || false; - item.position = item.position || 'top'; - item.weight = item.weight || 0; - - chart.boxes.push(item); - }, - - /** - * Remove a layoutItem from a chart - * @param {Chart} chart - the chart to remove the box from - * @param {Object} layoutItem - the item to remove from the layout - */ - removeBox: function(chart, layoutItem) { - var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; - if (index !== -1) { - chart.boxes.splice(index, 1); - } - }, - - /** - * Sets (or updates) options on the given `item`. - * @param {Chart} chart - the chart in which the item lives (or will be added to) - * @param {Object} item - the item to configure with the given options - * @param {Object} options - the new item options. - */ - configure: function(chart, item, options) { - var props = ['fullWidth', 'position', 'weight']; - var ilen = props.length; - var i = 0; - var prop; - - for (; i < ilen; ++i) { - prop = props[i]; - if (options.hasOwnProperty(prop)) { - item[prop] = options[prop]; - } - } - }, - - /** - * Fits boxes of the given chart into the given size by having each box measure itself - * then running a fitting algorithm - * @param {Chart} chart - the chart - * @param {Number} width - the width to fit into - * @param {Number} height - the height to fit into - */ - update: function(chart, width, height) { - if (!chart) { - return; - } - - var layoutOptions = chart.options.layout || {}; - var padding = helpers.options.toPadding(layoutOptions.padding); - var leftPadding = padding.left; - var rightPadding = padding.right; - var topPadding = padding.top; - var bottomPadding = padding.bottom; - - var leftBoxes = filterByPosition(chart.boxes, 'left'); - var rightBoxes = filterByPosition(chart.boxes, 'right'); - var topBoxes = filterByPosition(chart.boxes, 'top'); - var bottomBoxes = filterByPosition(chart.boxes, 'bottom'); - var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea'); - - // Sort boxes by weight. A higher weight is further away from the chart area - sortByWeight(leftBoxes, true); - sortByWeight(rightBoxes, false); - sortByWeight(topBoxes, true); - sortByWeight(bottomBoxes, false); - - // Essentially we now have any number of boxes on each of the 4 sides. - // Our canvas looks like the following. - // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and - // B1 is the bottom axis - // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays - // These locations are single-box locations only, when trying to register a chartArea location that is already taken, - // an error will be thrown. - // - // |----------------------------------------------------| - // | T1 (Full Width) | - // |----------------------------------------------------| - // | | | T2 | | - // | |----|-------------------------------------|----| - // | | | C1 | | C2 | | - // | | |----| |----| | - // | | | | | - // | L1 | L2 | ChartArea (C0) | R1 | - // | | | | | - // | | |----| |----| | - // | | | C3 | | C4 | | - // | |----|-------------------------------------|----| - // | | | B1 | | - // |----------------------------------------------------| - // | B2 (Full Width) | - // |----------------------------------------------------| - // - // What we do to find the best sizing, we do the following - // 1. Determine the minimum size of the chart area. - // 2. Split the remaining width equally between each vertical axis - // 3. Split the remaining height equally between each horizontal axis - // 4. Give each layout the maximum size it can be. The layout will return it's minimum size - // 5. Adjust the sizes of each axis based on it's minimum reported size. - // 6. Refit each axis - // 7. Position each axis in the final location - // 8. Tell the chart the final location of the chart area - // 9. Tell any axes that overlay the chart area the positions of the chart area - - // Step 1 - var chartWidth = width - leftPadding - rightPadding; - var chartHeight = height - topPadding - bottomPadding; - var chartAreaWidth = chartWidth / 2; // min 50% - var chartAreaHeight = chartHeight / 2; // min 50% - - // Step 2 - var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length); - - // Step 3 - var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length); - - // Step 4 - var maxChartAreaWidth = chartWidth; - var maxChartAreaHeight = chartHeight; - var minBoxSizes = []; - - function getMinimumBoxSize(box) { - var minSize; - var isHorizontal = box.isHorizontal(); - - if (isHorizontal) { - minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight); - maxChartAreaHeight -= minSize.height; - } else { - minSize = box.update(verticalBoxWidth, maxChartAreaHeight); - maxChartAreaWidth -= minSize.width; - } - - minBoxSizes.push({ - horizontal: isHorizontal, - minSize: minSize, - box: box, - }); - } - - helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize); - - // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478) - var maxHorizontalLeftPadding = 0; - var maxHorizontalRightPadding = 0; - var maxVerticalTopPadding = 0; - var maxVerticalBottomPadding = 0; - - helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) { - if (horizontalBox.getPadding) { - var boxPadding = horizontalBox.getPadding(); - maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left); - maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right); - } - }); - - helpers.each(leftBoxes.concat(rightBoxes), function(verticalBox) { - if (verticalBox.getPadding) { - var boxPadding = verticalBox.getPadding(); - maxVerticalTopPadding = Math.max(maxVerticalTopPadding, boxPadding.top); - maxVerticalBottomPadding = Math.max(maxVerticalBottomPadding, boxPadding.bottom); - } - }); - - // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could - // be if the axes are drawn at their minimum sizes. - // Steps 5 & 6 - var totalLeftBoxesWidth = leftPadding; - var totalRightBoxesWidth = rightPadding; - var totalTopBoxesHeight = topPadding; - var totalBottomBoxesHeight = bottomPadding; - - // Function to fit a box - function fitBox(box) { - var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBox) { - return minBox.box === box; - }); - - if (minBoxSize) { - if (box.isHorizontal()) { - var scaleMargin = { - left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding), - right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding), - top: 0, - bottom: 0 - }; - - // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends - // on the margin. Sometimes they need to increase in size slightly - box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin); - } else { - box.update(minBoxSize.minSize.width, maxChartAreaHeight); - } - } - } - - // Update, and calculate the left and right margins for the horizontal boxes - helpers.each(leftBoxes.concat(rightBoxes), fitBox); - - helpers.each(leftBoxes, function(box) { - totalLeftBoxesWidth += box.width; - }); - - helpers.each(rightBoxes, function(box) { - totalRightBoxesWidth += box.width; - }); - - // Set the Left and Right margins for the horizontal boxes - helpers.each(topBoxes.concat(bottomBoxes), fitBox); - - // Figure out how much margin is on the top and bottom of the vertical boxes - helpers.each(topBoxes, function(box) { - totalTopBoxesHeight += box.height; - }); - - helpers.each(bottomBoxes, function(box) { - totalBottomBoxesHeight += box.height; - }); - - function finalFitVerticalBox(box) { - var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minSize) { - return minSize.box === box; - }); - - var scaleMargin = { - left: 0, - right: 0, - top: totalTopBoxesHeight, - bottom: totalBottomBoxesHeight - }; - - if (minBoxSize) { - box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin); - } - } - - // Let the left layout know the final margin - helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox); - - // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance) - totalLeftBoxesWidth = leftPadding; - totalRightBoxesWidth = rightPadding; - totalTopBoxesHeight = topPadding; - totalBottomBoxesHeight = bottomPadding; - - helpers.each(leftBoxes, function(box) { - totalLeftBoxesWidth += box.width; - }); - - helpers.each(rightBoxes, function(box) { - totalRightBoxesWidth += box.width; - }); - - helpers.each(topBoxes, function(box) { - totalTopBoxesHeight += box.height; - }); - helpers.each(bottomBoxes, function(box) { - totalBottomBoxesHeight += box.height; - }); - - // We may be adding some padding to account for rotated x axis labels - var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0); - totalLeftBoxesWidth += leftPaddingAddition; - totalRightBoxesWidth += Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0); - - var topPaddingAddition = Math.max(maxVerticalTopPadding - totalTopBoxesHeight, 0); - totalTopBoxesHeight += topPaddingAddition; - totalBottomBoxesHeight += Math.max(maxVerticalBottomPadding - totalBottomBoxesHeight, 0); - - // Figure out if our chart area changed. This would occur if the dataset layout label rotation - // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do - // without calling `fit` again - var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight; - var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth; - - if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) { - helpers.each(leftBoxes, function(box) { - box.height = newMaxChartAreaHeight; - }); - - helpers.each(rightBoxes, function(box) { - box.height = newMaxChartAreaHeight; - }); - - helpers.each(topBoxes, function(box) { - if (!box.fullWidth) { - box.width = newMaxChartAreaWidth; - } - }); - - helpers.each(bottomBoxes, function(box) { - if (!box.fullWidth) { - box.width = newMaxChartAreaWidth; - } - }); - - maxChartAreaHeight = newMaxChartAreaHeight; - maxChartAreaWidth = newMaxChartAreaWidth; - } - - // Step 7 - Position the boxes - var left = leftPadding + leftPaddingAddition; - var top = topPadding + topPaddingAddition; - - function placeBox(box) { - if (box.isHorizontal()) { - box.left = box.fullWidth ? leftPadding : totalLeftBoxesWidth; - box.right = box.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth; - box.top = top; - box.bottom = top + box.height; - - // Move to next point - top = box.bottom; - - } else { - - box.left = left; - box.right = left + box.width; - box.top = totalTopBoxesHeight; - box.bottom = totalTopBoxesHeight + maxChartAreaHeight; - - // Move to next point - left = box.right; - } - } - - helpers.each(leftBoxes.concat(topBoxes), placeBox); - - // Account for chart width and height - left += maxChartAreaWidth; - top += maxChartAreaHeight; - - helpers.each(rightBoxes, placeBox); - helpers.each(bottomBoxes, placeBox); - - // Step 8 - chart.chartArea = { - left: totalLeftBoxesWidth, - top: totalTopBoxesHeight, - right: totalLeftBoxesWidth + maxChartAreaWidth, - bottom: totalTopBoxesHeight + maxChartAreaHeight - }; - - // Step 9 - helpers.each(chartAreaBoxes, function(box) { - box.left = chart.chartArea.left; - box.top = chart.chartArea.top; - box.right = chart.chartArea.right; - box.bottom = chart.chartArea.bottom; - - box.update(maxChartAreaWidth, maxChartAreaHeight); - }); - } -}; - -},{"46":46}],32:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var helpers = require(46); - -defaults._set('global', { - plugins: {} -}); - -/** - * The plugin service singleton - * @namespace Chart.plugins - * @since 2.1.0 - */ -module.exports = { - /** - * Globally registered plugins. - * @private - */ - _plugins: [], - - /** - * This identifier is used to invalidate the descriptors cache attached to each chart - * when a global plugin is registered or unregistered. In this case, the cache ID is - * incremented and descriptors are regenerated during following API calls. - * @private - */ - _cacheId: 0, - - /** - * Registers the given plugin(s) if not already registered. - * @param {Array|Object} plugins plugin instance(s). - */ - register: function(plugins) { - var p = this._plugins; - ([]).concat(plugins).forEach(function(plugin) { - if (p.indexOf(plugin) === -1) { - p.push(plugin); - } - }); - - this._cacheId++; - }, - - /** - * Unregisters the given plugin(s) only if registered. - * @param {Array|Object} plugins plugin instance(s). - */ - unregister: function(plugins) { - var p = this._plugins; - ([]).concat(plugins).forEach(function(plugin) { - var idx = p.indexOf(plugin); - if (idx !== -1) { - p.splice(idx, 1); - } - }); - - this._cacheId++; - }, - - /** - * Remove all registered plugins. - * @since 2.1.5 - */ - clear: function() { - this._plugins = []; - this._cacheId++; - }, - - /** - * Returns the number of registered plugins? - * @returns {Number} - * @since 2.1.5 - */ - count: function() { - return this._plugins.length; - }, - - /** - * Returns all registered plugin instances. - * @returns {Array} array of plugin objects. - * @since 2.1.5 - */ - getAll: function() { - return this._plugins; - }, - - /** - * Calls enabled plugins for `chart` on the specified hook and with the given args. - * This method immediately returns as soon as a plugin explicitly returns false. The - * returned value can be used, for instance, to interrupt the current action. - * @param {Object} chart - The chart instance for which plugins should be called. - * @param {String} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). - * @param {Array} [args] - Extra arguments to apply to the hook call. - * @returns {Boolean} false if any of the plugins return false, else returns true. - */ - notify: function(chart, hook, args) { - var descriptors = this.descriptors(chart); - var ilen = descriptors.length; - var i, descriptor, plugin, params, method; - - for (i = 0; i < ilen; ++i) { - descriptor = descriptors[i]; - plugin = descriptor.plugin; - method = plugin[hook]; - if (typeof method === 'function') { - params = [chart].concat(args || []); - params.push(descriptor.options); - if (method.apply(plugin, params) === false) { - return false; - } - } - } - - return true; - }, - - /** - * Returns descriptors of enabled plugins for the given chart. - * @returns {Array} [{ plugin, options }] - * @private - */ - descriptors: function(chart) { - var cache = chart.$plugins || (chart.$plugins = {}); - if (cache.id === this._cacheId) { - return cache.descriptors; - } - - var plugins = []; - var descriptors = []; - var config = (chart && chart.config) || {}; - var options = (config.options && config.options.plugins) || {}; - - this._plugins.concat(config.plugins || []).forEach(function(plugin) { - var idx = plugins.indexOf(plugin); - if (idx !== -1) { - return; - } - - var id = plugin.id; - var opts = options[id]; - if (opts === false) { - return; - } - - if (opts === true) { - opts = helpers.clone(defaults.global.plugins[id]); - } - - plugins.push(plugin); - descriptors.push({ - plugin: plugin, - options: opts || {} - }); - }); - - cache.descriptors = descriptors; - cache.id = this._cacheId; - return descriptors; - }, - - /** - * Invalidates cache for the given chart: descriptors hold a reference on plugin option, - * but in some cases, this reference can be changed by the user when updating options. - * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 - * @private - */ - _invalidate: function(chart) { - delete chart.$plugins; - } -}; - -/** - * Plugin extension hooks. - * @interface IPlugin - * @since 2.1.0 - */ -/** - * @method IPlugin#beforeInit - * @desc Called before initializing `chart`. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#afterInit - * @desc Called after `chart` has been initialized and before the first update. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeUpdate - * @desc Called before updating `chart`. If any plugin returns `false`, the update - * is cancelled (and thus subsequent render(s)) until another `update` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart update. - */ -/** - * @method IPlugin#afterUpdate - * @desc Called after `chart` has been updated and before rendering. Note that this - * hook will not be called if the chart update has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeDatasetsUpdate - * @desc Called before updating the `chart` datasets. If any plugin returns `false`, - * the datasets update is cancelled until another `update` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - * @returns {Boolean} false to cancel the datasets update. - * @since version 2.1.5 -*/ -/** - * @method IPlugin#afterDatasetsUpdate - * @desc Called after the `chart` datasets have been updated. Note that this hook - * will not be called if the datasets update has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - * @since version 2.1.5 - */ -/** - * @method IPlugin#beforeDatasetUpdate - * @desc Called before updating the `chart` dataset at the given `args.index`. If any plugin - * returns `false`, the datasets update is cancelled until another `update` is triggered. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Number} args.index - The dataset index. - * @param {Object} args.meta - The dataset metadata. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart datasets drawing. - */ -/** - * @method IPlugin#afterDatasetUpdate - * @desc Called after the `chart` datasets at the given `args.index` has been updated. Note - * that this hook will not be called if the datasets update has been previously cancelled. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Number} args.index - The dataset index. - * @param {Object} args.meta - The dataset metadata. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeLayout - * @desc Called before laying out `chart`. If any plugin returns `false`, - * the layout update is cancelled until another `update` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart layout. - */ -/** - * @method IPlugin#afterLayout - * @desc Called after the `chart` has been layed out. Note that this hook will not - * be called if the layout update has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeRender - * @desc Called before rendering `chart`. If any plugin returns `false`, - * the rendering is cancelled until another `render` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart rendering. - */ -/** - * @method IPlugin#afterRender - * @desc Called after the `chart` has been fully rendered (and animation completed). Note - * that this hook will not be called if the rendering has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeDraw - * @desc Called before drawing `chart` at every animation frame specified by the given - * easing value. If any plugin returns `false`, the frame drawing is cancelled until - * another `render` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart drawing. - */ -/** - * @method IPlugin#afterDraw - * @desc Called after the `chart` has been drawn for the specific easing value. Note - * that this hook will not be called if the drawing has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeDatasetsDraw - * @desc Called before drawing the `chart` datasets. If any plugin returns `false`, - * the datasets drawing is cancelled until another `render` is triggered. - * @param {Chart.Controller} chart - The chart instance. - * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart datasets drawing. - */ -/** - * @method IPlugin#afterDatasetsDraw - * @desc Called after the `chart` datasets have been drawn. Note that this hook - * will not be called if the datasets drawing has been previously cancelled. - * @param {Chart.Controller} chart - The chart instance. - * @param {Number} easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeDatasetDraw - * @desc Called before drawing the `chart` dataset at the given `args.index` (datasets - * are drawn in the reverse order). If any plugin returns `false`, the datasets drawing - * is cancelled until another `render` is triggered. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Number} args.index - The dataset index. - * @param {Object} args.meta - The dataset metadata. - * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart datasets drawing. - */ -/** - * @method IPlugin#afterDatasetDraw - * @desc Called after the `chart` datasets at the given `args.index` have been drawn - * (datasets are drawn in the reverse order). Note that this hook will not be called - * if the datasets drawing has been previously cancelled. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Number} args.index - The dataset index. - * @param {Object} args.meta - The dataset metadata. - * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeTooltipDraw - * @desc Called before drawing the `tooltip`. If any plugin returns `false`, - * the tooltip drawing is cancelled until another `render` is triggered. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Object} args.tooltip - The tooltip. - * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - * @returns {Boolean} `false` to cancel the chart tooltip drawing. - */ -/** - * @method IPlugin#afterTooltipDraw - * @desc Called after drawing the `tooltip`. Note that this hook will not - * be called if the tooltip drawing has been previously cancelled. - * @param {Chart} chart - The chart instance. - * @param {Object} args - The call arguments. - * @param {Object} args.tooltip - The tooltip. - * @param {Number} args.easingValue - The current animation value, between 0.0 and 1.0. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#beforeEvent - * @desc Called before processing the specified `event`. If any plugin returns `false`, - * the event will be discarded. - * @param {Chart.Controller} chart - The chart instance. - * @param {IEvent} event - The event object. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#afterEvent - * @desc Called after the `event` has been consumed. Note that this hook - * will not be called if the `event` has been previously discarded. - * @param {Chart.Controller} chart - The chart instance. - * @param {IEvent} event - The event object. - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#resize - * @desc Called after the chart as been resized. - * @param {Chart.Controller} chart - The chart instance. - * @param {Number} size - The new canvas display size (eq. canvas.style width & height). - * @param {Object} options - The plugin options. - */ -/** - * @method IPlugin#destroy - * @desc Called after the chart as been destroyed. - * @param {Chart.Controller} chart - The chart instance. - * @param {Object} options - The plugin options. - */ - -},{"26":26,"46":46}],33:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); -var Ticks = require(35); - -defaults._set('scale', { - display: true, - position: 'left', - offset: false, - - // grid line settings - gridLines: { - display: true, - color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1, - drawBorder: true, - drawOnChartArea: true, - drawTicks: true, - tickMarkLength: 10, - zeroLineWidth: 1, - zeroLineColor: 'rgba(0,0,0,0.25)', - zeroLineBorderDash: [], - zeroLineBorderDashOffset: 0.0, - offsetGridLines: false, - borderDash: [], - borderDashOffset: 0.0 - }, - - // scale label - scaleLabel: { - // display property - display: false, - - // actual label - labelString: '', - - // line height - lineHeight: 1.2, - - // top/bottom padding - padding: { - top: 4, - bottom: 4 - } - }, - - // label settings - ticks: { - beginAtZero: false, - minRotation: 0, - maxRotation: 50, - mirror: false, - padding: 0, - reverse: false, - display: true, - autoSkip: true, - autoSkipPadding: 0, - labelOffset: 0, - // We pass through arrays to be rendered as multiline labels, we convert Others to strings here. - callback: Ticks.formatters.values, - minor: {}, - major: {} - } -}); - -function labelsFromTicks(ticks) { - var labels = []; - var i, ilen; - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - labels.push(ticks[i].label); - } - - return labels; -} - -function getLineValue(scale, index, offsetGridLines) { - var lineValue = scale.getPixelForTick(index); - - if (offsetGridLines) { - if (index === 0) { - lineValue -= (scale.getPixelForTick(1) - lineValue) / 2; - } else { - lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2; - } - } - return lineValue; -} - -function computeTextSize(context, tick, font) { - return helpers.isArray(tick) ? - helpers.longestText(context, font, tick) : - context.measureText(tick).width; -} - -function parseFontOptions(options) { - var valueOrDefault = helpers.valueOrDefault; - var globalDefaults = defaults.global; - var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); - var style = valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle); - var family = valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily); - - return { - size: size, - style: style, - family: family, - font: helpers.fontString(size, style, family) - }; -} - -function parseLineHeight(options) { - return helpers.options.toLineHeight( - helpers.valueOrDefault(options.lineHeight, 1.2), - helpers.valueOrDefault(options.fontSize, defaults.global.defaultFontSize)); -} - -module.exports = Element.extend({ - /** - * Get the padding needed for the scale - * @method getPadding - * @private - * @returns {Padding} the necessary padding - */ - getPadding: function() { - var me = this; - return { - left: me.paddingLeft || 0, - top: me.paddingTop || 0, - right: me.paddingRight || 0, - bottom: me.paddingBottom || 0 - }; - }, - - /** - * Returns the scale tick objects ({label, major}) - * @since 2.7 - */ - getTicks: function() { - return this._ticks; - }, - - // These methods are ordered by lifecyle. Utilities then follow. - // Any function defined here is inherited by all scale types. - // Any function can be extended by the scale type - - mergeTicksOptions: function() { - var ticks = this.options.ticks; - if (ticks.minor === false) { - ticks.minor = { - display: false - }; - } - if (ticks.major === false) { - ticks.major = { - display: false - }; - } - for (var key in ticks) { - if (key !== 'major' && key !== 'minor') { - if (typeof ticks.minor[key] === 'undefined') { - ticks.minor[key] = ticks[key]; - } - if (typeof ticks.major[key] === 'undefined') { - ticks.major[key] = ticks[key]; - } - } - } - }, - beforeUpdate: function() { - helpers.callback(this.options.beforeUpdate, [this]); - }, - - update: function(maxWidth, maxHeight, margins) { - var me = this; - var i, ilen, labels, label, ticks, tick; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = helpers.extend({ - left: 0, - right: 0, - top: 0, - bottom: 0 - }, margins); - me.longestTextCache = me.longestTextCache || {}; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - - // Data min/max - me.beforeDataLimits(); - me.determineDataLimits(); - me.afterDataLimits(); - - // Ticks - `this.ticks` is now DEPRECATED! - // Internal ticks are now stored as objects in the PRIVATE `this._ticks` member - // and must not be accessed directly from outside this class. `this.ticks` being - // around for long time and not marked as private, we can't change its structure - // without unexpected breaking changes. If you need to access the scale ticks, - // use scale.getTicks() instead. - - me.beforeBuildTicks(); - - // New implementations should return an array of objects but for BACKWARD COMPAT, - // we still support no return (`this.ticks` internally set by calling this method). - ticks = me.buildTicks() || []; - - me.afterBuildTicks(); - - me.beforeTickToLabelConversion(); - - // New implementations should return the formatted tick labels but for BACKWARD - // COMPAT, we still support no return (`this.ticks` internally changed by calling - // this method and supposed to contain only string values). - labels = me.convertTicksToLabels(ticks) || me.ticks; - - me.afterTickToLabelConversion(); - - me.ticks = labels; // BACKWARD COMPATIBILITY - - // IMPORTANT: from this point, we consider that `this.ticks` will NEVER change! - - // BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`) - for (i = 0, ilen = labels.length; i < ilen; ++i) { - label = labels[i]; - tick = ticks[i]; - if (!tick) { - ticks.push(tick = { - label: label, - major: false - }); - } else { - tick.label = label; - } - } - - me._ticks = ticks; - - // Tick Rotation - me.beforeCalculateTickRotation(); - me.calculateTickRotation(); - me.afterCalculateTickRotation(); - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - - }, - afterUpdate: function() { - helpers.callback(this.options.afterUpdate, [this]); - }, - - // - - beforeSetDimensions: function() { - helpers.callback(this.options.beforeSetDimensions, [this]); - }, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - }, - afterSetDimensions: function() { - helpers.callback(this.options.afterSetDimensions, [this]); - }, - - // Data limits - beforeDataLimits: function() { - helpers.callback(this.options.beforeDataLimits, [this]); - }, - determineDataLimits: helpers.noop, - afterDataLimits: function() { - helpers.callback(this.options.afterDataLimits, [this]); - }, - - // - beforeBuildTicks: function() { - helpers.callback(this.options.beforeBuildTicks, [this]); - }, - buildTicks: helpers.noop, - afterBuildTicks: function() { - helpers.callback(this.options.afterBuildTicks, [this]); - }, - - beforeTickToLabelConversion: function() { - helpers.callback(this.options.beforeTickToLabelConversion, [this]); - }, - convertTicksToLabels: function() { - var me = this; - // Convert ticks to strings - var tickOpts = me.options.ticks; - me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this); - }, - afterTickToLabelConversion: function() { - helpers.callback(this.options.afterTickToLabelConversion, [this]); - }, - - // - - beforeCalculateTickRotation: function() { - helpers.callback(this.options.beforeCalculateTickRotation, [this]); - }, - calculateTickRotation: function() { - var me = this; - var context = me.ctx; - var tickOpts = me.options.ticks; - var labels = labelsFromTicks(me._ticks); - - // Get the width of each grid by calculating the difference - // between x offsets between 0 and 1. - var tickFont = parseFontOptions(tickOpts); - context.font = tickFont.font; - - var labelRotation = tickOpts.minRotation || 0; - - if (labels.length && me.options.display && me.isHorizontal()) { - var originalLabelWidth = helpers.longestText(context, tickFont.font, labels, me.longestTextCache); - var labelWidth = originalLabelWidth; - var cosRotation, sinRotation; - - // Allow 3 pixels x2 padding either side for label readability - var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6; - - // Max label rotation can be set or default to 90 - also act as a loop counter - while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) { - var angleRadians = helpers.toRadians(labelRotation); - cosRotation = Math.cos(angleRadians); - sinRotation = Math.sin(angleRadians); - - if (sinRotation * originalLabelWidth > me.maxHeight) { - // go back one step - labelRotation--; - break; - } - - labelRotation++; - labelWidth = cosRotation * originalLabelWidth; - } - } - - me.labelRotation = labelRotation; - }, - afterCalculateTickRotation: function() { - helpers.callback(this.options.afterCalculateTickRotation, [this]); - }, - - // - - beforeFit: function() { - helpers.callback(this.options.beforeFit, [this]); - }, - fit: function() { - var me = this; - // Reset - var minSize = me.minSize = { - width: 0, - height: 0 - }; - - var labels = labelsFromTicks(me._ticks); - - var opts = me.options; - var tickOpts = opts.ticks; - var scaleLabelOpts = opts.scaleLabel; - var gridLineOpts = opts.gridLines; - var display = opts.display; - var isHorizontal = me.isHorizontal(); - - var tickFont = parseFontOptions(tickOpts); - var tickMarkLength = opts.gridLines.tickMarkLength; - - // Width - if (isHorizontal) { - // subtract the margins to line up with the chartArea if we are a full width scale - minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth; - } else { - minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0; - } - - // height - if (isHorizontal) { - minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0; - } else { - minSize.height = me.maxHeight; // fill all the height - } - - // Are we showing a title for the scale? - if (scaleLabelOpts.display && display) { - var scaleLabelLineHeight = parseLineHeight(scaleLabelOpts); - var scaleLabelPadding = helpers.options.toPadding(scaleLabelOpts.padding); - var deltaHeight = scaleLabelLineHeight + scaleLabelPadding.height; - - if (isHorizontal) { - minSize.height += deltaHeight; - } else { - minSize.width += deltaHeight; - } - } - - // Don't bother fitting the ticks if we are not showing them - if (tickOpts.display && display) { - var largestTextWidth = helpers.longestText(me.ctx, tickFont.font, labels, me.longestTextCache); - var tallestLabelHeightInLines = helpers.numberOfLabelLines(labels); - var lineSpace = tickFont.size * 0.5; - var tickPadding = me.options.ticks.padding; - - if (isHorizontal) { - // A horizontal axis is more constrained by the height. - me.longestLabelWidth = largestTextWidth; - - var angleRadians = helpers.toRadians(me.labelRotation); - var cosRotation = Math.cos(angleRadians); - var sinRotation = Math.sin(angleRadians); - - // TODO - improve this calculation - var labelHeight = (sinRotation * largestTextWidth) - + (tickFont.size * tallestLabelHeightInLines) - + (lineSpace * (tallestLabelHeightInLines - 1)) - + lineSpace; // padding - - minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding); - - me.ctx.font = tickFont.font; - var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.font); - var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.font); - - // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned - // which means that the right padding is dominated by the font height - if (me.labelRotation !== 0) { - me.paddingLeft = opts.position === 'bottom' ? (cosRotation * firstLabelWidth) + 3 : (cosRotation * lineSpace) + 3; // add 3 px to move away from canvas edges - me.paddingRight = opts.position === 'bottom' ? (cosRotation * lineSpace) + 3 : (cosRotation * lastLabelWidth) + 3; - } else { - me.paddingLeft = firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges - me.paddingRight = lastLabelWidth / 2 + 3; - } - } else { - // A vertical axis is more constrained by the width. Labels are the - // dominant factor here, so get that length first and account for padding - if (tickOpts.mirror) { - largestTextWidth = 0; - } else { - // use lineSpace for consistency with horizontal axis - // tickPadding is not implemented for horizontal - largestTextWidth += tickPadding + lineSpace; - } - - minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth); - - me.paddingTop = tickFont.size / 2; - me.paddingBottom = tickFont.size / 2; - } - } - - me.handleMargins(); - - me.width = minSize.width; - me.height = minSize.height; - }, - - /** - * Handle margins and padding interactions - * @private - */ - handleMargins: function() { - var me = this; - if (me.margins) { - me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0); - me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0); - me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0); - me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0); - } - }, - - afterFit: function() { - helpers.callback(this.options.afterFit, [this]); - }, - - // Shared Methods - isHorizontal: function() { - return this.options.position === 'top' || this.options.position === 'bottom'; - }, - isFullWidth: function() { - return (this.options.fullWidth); - }, - - // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not - getRightValue: function(rawValue) { - // Null and undefined values first - if (helpers.isNullOrUndef(rawValue)) { - return NaN; - } - // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values - if (typeof rawValue === 'number' && !isFinite(rawValue)) { - return NaN; - } - // If it is in fact an object, dive in one more level - if (rawValue) { - if (this.isHorizontal()) { - if (rawValue.x !== undefined) { - return this.getRightValue(rawValue.x); - } - } else if (rawValue.y !== undefined) { - return this.getRightValue(rawValue.y); - } - } - - // Value is good, return it - return rawValue; - }, - - /** - * Used to get the value to display in the tooltip for the data at the given index - * @param index - * @param datasetIndex - */ - getLabelForIndex: helpers.noop, - - /** - * Returns the location of the given data point. Value can either be an index or a numerical value - * The coordinate (0, 0) is at the upper-left corner of the canvas - * @param value - * @param index - * @param datasetIndex - */ - getPixelForValue: helpers.noop, - - /** - * Used to get the data value from a given pixel. This is the inverse of getPixelForValue - * The coordinate (0, 0) is at the upper-left corner of the canvas - * @param pixel - */ - getValueForPixel: helpers.noop, - - /** - * Returns the location of the tick at the given index - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getPixelForTick: function(index) { - var me = this; - var offset = me.options.offset; - if (me.isHorizontal()) { - var innerWidth = me.width - (me.paddingLeft + me.paddingRight); - var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1); - var pixel = (tickWidth * index) + me.paddingLeft; - - if (offset) { - pixel += tickWidth / 2; - } - - var finalVal = me.left + Math.round(pixel); - finalVal += me.isFullWidth() ? me.margins.left : 0; - return finalVal; - } - var innerHeight = me.height - (me.paddingTop + me.paddingBottom); - return me.top + (index * (innerHeight / (me._ticks.length - 1))); - }, - - /** - * Utility for getting the pixel location of a percentage of scale - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getPixelForDecimal: function(decimal) { - var me = this; - if (me.isHorizontal()) { - var innerWidth = me.width - (me.paddingLeft + me.paddingRight); - var valueOffset = (innerWidth * decimal) + me.paddingLeft; - - var finalVal = me.left + Math.round(valueOffset); - finalVal += me.isFullWidth() ? me.margins.left : 0; - return finalVal; - } - return me.top + (decimal * me.height); - }, - - /** - * Returns the pixel for the minimum chart value - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getBasePixel: function() { - return this.getPixelForValue(this.getBaseValue()); - }, - - getBaseValue: function() { - var me = this; - var min = me.min; - var max = me.max; - - return me.beginAtZero ? 0 : - min < 0 && max < 0 ? max : - min > 0 && max > 0 ? min : - 0; - }, - - /** - * Returns a subset of ticks to be plotted to avoid overlapping labels. - * @private - */ - _autoSkip: function(ticks) { - var skipRatio; - var me = this; - var isHorizontal = me.isHorizontal(); - var optionTicks = me.options.ticks.minor; - var tickCount = ticks.length; - var labelRotationRadians = helpers.toRadians(me.labelRotation); - var cosRotation = Math.cos(labelRotationRadians); - var longestRotatedLabel = me.longestLabelWidth * cosRotation; - var result = []; - var i, tick, shouldSkip; - - // figure out the maximum number of gridlines to show - var maxTicks; - if (optionTicks.maxTicksLimit) { - maxTicks = optionTicks.maxTicksLimit; - } - - if (isHorizontal) { - skipRatio = false; - - if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) { - skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight))); - } - - // if they defined a max number of optionTicks, - // increase skipRatio until that number is met - if (maxTicks && tickCount > maxTicks) { - skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks)); - } - } - - for (i = 0; i < tickCount; i++) { - tick = ticks[i]; - - // Since we always show the last tick,we need may need to hide the last shown one before - shouldSkip = (skipRatio > 1 && i % skipRatio > 0) || (i % skipRatio === 0 && i + skipRatio >= tickCount); - if (shouldSkip && i !== tickCount - 1) { - // leave tick in place but make sure it's not displayed (#4635) - delete tick.label; - } - result.push(tick); - } - return result; - }, - - // Actually draw the scale on the canvas - // @param {rectangle} chartArea : the area of the chart to draw full grid lines on - draw: function(chartArea) { - var me = this; - var options = me.options; - if (!options.display) { - return; - } - - var context = me.ctx; - var globalDefaults = defaults.global; - var optionTicks = options.ticks.minor; - var optionMajorTicks = options.ticks.major || optionTicks; - var gridLines = options.gridLines; - var scaleLabel = options.scaleLabel; - - var isRotated = me.labelRotation !== 0; - var isHorizontal = me.isHorizontal(); - - var ticks = optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks(); - var tickFontColor = helpers.valueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor); - var tickFont = parseFontOptions(optionTicks); - var majorTickFontColor = helpers.valueOrDefault(optionMajorTicks.fontColor, globalDefaults.defaultFontColor); - var majorTickFont = parseFontOptions(optionMajorTicks); - - var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0; - - var scaleLabelFontColor = helpers.valueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor); - var scaleLabelFont = parseFontOptions(scaleLabel); - var scaleLabelPadding = helpers.options.toPadding(scaleLabel.padding); - var labelRotationRadians = helpers.toRadians(me.labelRotation); - - var itemsToDraw = []; - - var axisWidth = me.options.gridLines.lineWidth; - var xTickStart = options.position === 'right' ? me.left : me.right - axisWidth - tl; - var xTickEnd = options.position === 'right' ? me.left + tl : me.right; - var yTickStart = options.position === 'bottom' ? me.top + axisWidth : me.bottom - tl - axisWidth; - var yTickEnd = options.position === 'bottom' ? me.top + axisWidth + tl : me.bottom + axisWidth; - - helpers.each(ticks, function(tick, index) { - // autoskipper skipped this tick (#4635) - if (helpers.isNullOrUndef(tick.label)) { - return; - } - - var label = tick.label; - var lineWidth, lineColor, borderDash, borderDashOffset; - if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) { - // Draw the first index specially - lineWidth = gridLines.zeroLineWidth; - lineColor = gridLines.zeroLineColor; - borderDash = gridLines.zeroLineBorderDash; - borderDashOffset = gridLines.zeroLineBorderDashOffset; - } else { - lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, index); - lineColor = helpers.valueAtIndexOrDefault(gridLines.color, index); - borderDash = helpers.valueOrDefault(gridLines.borderDash, globalDefaults.borderDash); - borderDashOffset = helpers.valueOrDefault(gridLines.borderDashOffset, globalDefaults.borderDashOffset); - } - - // Common properties - var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY; - var textAlign = 'middle'; - var textBaseline = 'middle'; - var tickPadding = optionTicks.padding; - - if (isHorizontal) { - var labelYOffset = tl + tickPadding; - - if (options.position === 'bottom') { - // bottom - textBaseline = !isRotated ? 'top' : 'middle'; - textAlign = !isRotated ? 'center' : 'right'; - labelY = me.top + labelYOffset; - } else { - // top - textBaseline = !isRotated ? 'bottom' : 'middle'; - textAlign = !isRotated ? 'center' : 'left'; - labelY = me.bottom - labelYOffset; - } - - var xLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1); - if (xLineValue < me.left) { - lineColor = 'rgba(0,0,0,0)'; - } - xLineValue += helpers.aliasPixel(lineWidth); - - labelX = me.getPixelForTick(index) + optionTicks.labelOffset; // x values for optionTicks (need to consider offsetLabel option) - - tx1 = tx2 = x1 = x2 = xLineValue; - ty1 = yTickStart; - ty2 = yTickEnd; - y1 = chartArea.top; - y2 = chartArea.bottom + axisWidth; - } else { - var isLeft = options.position === 'left'; - var labelXOffset; - - if (optionTicks.mirror) { - textAlign = isLeft ? 'left' : 'right'; - labelXOffset = tickPadding; - } else { - textAlign = isLeft ? 'right' : 'left'; - labelXOffset = tl + tickPadding; - } - - labelX = isLeft ? me.right - labelXOffset : me.left + labelXOffset; - - var yLineValue = getLineValue(me, index, gridLines.offsetGridLines && ticks.length > 1); - if (yLineValue < me.top) { - lineColor = 'rgba(0,0,0,0)'; - } - yLineValue += helpers.aliasPixel(lineWidth); - - labelY = me.getPixelForTick(index) + optionTicks.labelOffset; - - tx1 = xTickStart; - tx2 = xTickEnd; - x1 = chartArea.left; - x2 = chartArea.right + axisWidth; - ty1 = ty2 = y1 = y2 = yLineValue; - } - - itemsToDraw.push({ - tx1: tx1, - ty1: ty1, - tx2: tx2, - ty2: ty2, - x1: x1, - y1: y1, - x2: x2, - y2: y2, - labelX: labelX, - labelY: labelY, - glWidth: lineWidth, - glColor: lineColor, - glBorderDash: borderDash, - glBorderDashOffset: borderDashOffset, - rotation: -1 * labelRotationRadians, - label: label, - major: tick.major, - textBaseline: textBaseline, - textAlign: textAlign - }); - }); - - // Draw all of the tick labels, tick marks, and grid lines at the correct places - helpers.each(itemsToDraw, function(itemToDraw) { - if (gridLines.display) { - context.save(); - context.lineWidth = itemToDraw.glWidth; - context.strokeStyle = itemToDraw.glColor; - if (context.setLineDash) { - context.setLineDash(itemToDraw.glBorderDash); - context.lineDashOffset = itemToDraw.glBorderDashOffset; - } - - context.beginPath(); - - if (gridLines.drawTicks) { - context.moveTo(itemToDraw.tx1, itemToDraw.ty1); - context.lineTo(itemToDraw.tx2, itemToDraw.ty2); - } - - if (gridLines.drawOnChartArea) { - context.moveTo(itemToDraw.x1, itemToDraw.y1); - context.lineTo(itemToDraw.x2, itemToDraw.y2); - } - - context.stroke(); - context.restore(); - } - - if (optionTicks.display) { - // Make sure we draw text in the correct color and font - context.save(); - context.translate(itemToDraw.labelX, itemToDraw.labelY); - context.rotate(itemToDraw.rotation); - context.font = itemToDraw.major ? majorTickFont.font : tickFont.font; - context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor; - context.textBaseline = itemToDraw.textBaseline; - context.textAlign = itemToDraw.textAlign; - - var label = itemToDraw.label; - if (helpers.isArray(label)) { - var lineCount = label.length; - var lineHeight = tickFont.size * 1.5; - var y = me.isHorizontal() ? 0 : -lineHeight * (lineCount - 1) / 2; - - for (var i = 0; i < lineCount; ++i) { - // We just make sure the multiline element is a string here.. - context.fillText('' + label[i], 0, y); - // apply same lineSpacing as calculated @ L#320 - y += lineHeight; - } - } else { - context.fillText(label, 0, 0); - } - context.restore(); - } - }); - - if (scaleLabel.display) { - // Draw the scale label - var scaleLabelX; - var scaleLabelY; - var rotation = 0; - var halfLineHeight = parseLineHeight(scaleLabel) / 2; - - if (isHorizontal) { - scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width - scaleLabelY = options.position === 'bottom' - ? me.bottom - halfLineHeight - scaleLabelPadding.bottom - : me.top + halfLineHeight + scaleLabelPadding.top; - } else { - var isLeft = options.position === 'left'; - scaleLabelX = isLeft - ? me.left + halfLineHeight + scaleLabelPadding.top - : me.right - halfLineHeight - scaleLabelPadding.top; - scaleLabelY = me.top + ((me.bottom - me.top) / 2); - rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI; - } - - context.save(); - context.translate(scaleLabelX, scaleLabelY); - context.rotate(rotation); - context.textAlign = 'center'; - context.textBaseline = 'middle'; - context.fillStyle = scaleLabelFontColor; // render in correct colour - context.font = scaleLabelFont.font; - context.fillText(scaleLabel.labelString, 0, 0); - context.restore(); - } - - if (gridLines.drawBorder) { - // Draw the line at the edge of the axis - context.lineWidth = helpers.valueAtIndexOrDefault(gridLines.lineWidth, 0); - context.strokeStyle = helpers.valueAtIndexOrDefault(gridLines.color, 0); - var x1 = me.left; - var x2 = me.right + axisWidth; - var y1 = me.top; - var y2 = me.bottom + axisWidth; - - var aliasPixel = helpers.aliasPixel(context.lineWidth); - if (isHorizontal) { - y1 = y2 = options.position === 'top' ? me.bottom : me.top; - y1 += aliasPixel; - y2 += aliasPixel; - } else { - x1 = x2 = options.position === 'left' ? me.right : me.left; - x1 += aliasPixel; - x2 += aliasPixel; - } - - context.beginPath(); - context.moveTo(x1, y1); - context.lineTo(x2, y2); - context.stroke(); - } - } -}); - -},{"26":26,"27":27,"35":35,"46":46}],34:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var helpers = require(46); -var layouts = require(31); - -module.exports = { - // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then - // use the new chart options to grab the correct scale - constructors: {}, - // Use a registration function so that we can move to an ES6 map when we no longer need to support - // old browsers - - // Scale config defaults - defaults: {}, - registerScaleType: function(type, scaleConstructor, scaleDefaults) { - this.constructors[type] = scaleConstructor; - this.defaults[type] = helpers.clone(scaleDefaults); - }, - getScaleConstructor: function(type) { - return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined; - }, - getScaleDefaults: function(type) { - // Return the scale defaults merged with the global settings so that we always use the latest ones - return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {}; - }, - updateScaleDefaults: function(type, additions) { - var me = this; - if (me.defaults.hasOwnProperty(type)) { - me.defaults[type] = helpers.extend(me.defaults[type], additions); - } - }, - addScalesToLayout: function(chart) { - // Adds each scale to the chart.boxes array to be sized accordingly - helpers.each(chart.scales, function(scale) { - // Set ILayoutItem parameters for backwards compatibility - scale.fullWidth = scale.options.fullWidth; - scale.position = scale.options.position; - scale.weight = scale.options.weight; - layouts.addBox(chart, scale); - }); - } -}; - -},{"26":26,"31":31,"46":46}],35:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); - -/** - * Namespace to hold static tick generation functions - * @namespace Chart.Ticks - */ -module.exports = { - /** - * Namespace to hold formatters for different types of ticks - * @namespace Chart.Ticks.formatters - */ - formatters: { - /** - * Formatter for value labels - * @method Chart.Ticks.formatters.values - * @param value the value to display - * @return {String|Array} the label to display - */ - values: function(value) { - return helpers.isArray(value) ? value : '' + value; - }, - - /** - * Formatter for linear numeric ticks - * @method Chart.Ticks.formatters.linear - * @param tickValue {Number} the value to be formatted - * @param index {Number} the position of the tickValue parameter in the ticks array - * @param ticks {Array<Number>} the list of ticks being converted - * @return {String} string representation of the tickValue parameter - */ - linear: function(tickValue, index, ticks) { - // If we have lots of ticks, don't use the ones - var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0]; - - // If we have a number like 2.5 as the delta, figure out how many decimal places we need - if (Math.abs(delta) > 1) { - if (tickValue !== Math.floor(tickValue)) { - // not an integer - delta = tickValue - Math.floor(tickValue); - } - } - - var logDelta = helpers.log10(Math.abs(delta)); - var tickString = ''; - - if (tickValue !== 0) { - var maxTick = Math.max(Math.abs(ticks[0]), Math.abs(ticks[ticks.length - 1])); - if (maxTick < 1e-4) { // all ticks are small numbers; use scientific notation - var logTick = helpers.log10(Math.abs(tickValue)); - tickString = tickValue.toExponential(Math.floor(logTick) - Math.floor(logDelta)); - } else { - var numDecimal = -1 * Math.floor(logDelta); - numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places - tickString = tickValue.toFixed(numDecimal); - } - } else { - tickString = '0'; // never show decimal places for 0 - } - - return tickString; - }, - - logarithmic: function(tickValue, index, ticks) { - var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue)))); - - if (tickValue === 0) { - return '0'; - } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) { - return tickValue.toExponential(); - } - return ''; - } - } -}; - -},{"46":46}],36:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); - -defaults._set('global', { - tooltips: { - enabled: true, - custom: null, - mode: 'nearest', - position: 'average', - intersect: true, - backgroundColor: 'rgba(0,0,0,0.8)', - titleFontStyle: 'bold', - titleSpacing: 2, - titleMarginBottom: 6, - titleFontColor: '#fff', - titleAlign: 'left', - bodySpacing: 2, - bodyFontColor: '#fff', - bodyAlign: 'left', - footerFontStyle: 'bold', - footerSpacing: 2, - footerMarginTop: 6, - footerFontColor: '#fff', - footerAlign: 'left', - yPadding: 6, - xPadding: 6, - caretPadding: 2, - caretSize: 5, - cornerRadius: 6, - multiKeyBackground: '#fff', - displayColors: true, - borderColor: 'rgba(0,0,0,0)', - borderWidth: 0, - callbacks: { - // Args are: (tooltipItems, data) - beforeTitle: helpers.noop, - title: function(tooltipItems, data) { - // Pick first xLabel for now - var title = ''; - var labels = data.labels; - var labelCount = labels ? labels.length : 0; - - if (tooltipItems.length > 0) { - var item = tooltipItems[0]; - - if (item.xLabel) { - title = item.xLabel; - } else if (labelCount > 0 && item.index < labelCount) { - title = labels[item.index]; - } - } - - return title; - }, - afterTitle: helpers.noop, - - // Args are: (tooltipItems, data) - beforeBody: helpers.noop, - - // Args are: (tooltipItem, data) - beforeLabel: helpers.noop, - label: function(tooltipItem, data) { - var label = data.datasets[tooltipItem.datasetIndex].label || ''; - - if (label) { - label += ': '; - } - label += tooltipItem.yLabel; - return label; - }, - labelColor: function(tooltipItem, chart) { - var meta = chart.getDatasetMeta(tooltipItem.datasetIndex); - var activeElement = meta.data[tooltipItem.index]; - var view = activeElement._view; - return { - borderColor: view.borderColor, - backgroundColor: view.backgroundColor - }; - }, - labelTextColor: function() { - return this._options.bodyFontColor; - }, - afterLabel: helpers.noop, - - // Args are: (tooltipItems, data) - afterBody: helpers.noop, - - // Args are: (tooltipItems, data) - beforeFooter: helpers.noop, - footer: helpers.noop, - afterFooter: helpers.noop - } - } -}); - -var positioners = { - /** - * Average mode places the tooltip at the average position of the elements shown - * @function Chart.Tooltip.positioners.average - * @param elements {ChartElement[]} the elements being displayed in the tooltip - * @returns {Point} tooltip position - */ - average: function(elements) { - if (!elements.length) { - return false; - } - - var i, len; - var x = 0; - var y = 0; - var count = 0; - - for (i = 0, len = elements.length; i < len; ++i) { - var el = elements[i]; - if (el && el.hasValue()) { - var pos = el.tooltipPosition(); - x += pos.x; - y += pos.y; - ++count; - } - } - - return { - x: Math.round(x / count), - y: Math.round(y / count) - }; - }, - - /** - * Gets the tooltip position nearest of the item nearest to the event position - * @function Chart.Tooltip.positioners.nearest - * @param elements {Chart.Element[]} the tooltip elements - * @param eventPosition {Point} the position of the event in canvas coordinates - * @returns {Point} the tooltip position - */ - nearest: function(elements, eventPosition) { - var x = eventPosition.x; - var y = eventPosition.y; - var minDistance = Number.POSITIVE_INFINITY; - var i, len, nearestElement; - - for (i = 0, len = elements.length; i < len; ++i) { - var el = elements[i]; - if (el && el.hasValue()) { - var center = el.getCenterPoint(); - var d = helpers.distanceBetweenPoints(eventPosition, center); - - if (d < minDistance) { - minDistance = d; - nearestElement = el; - } - } - } - - if (nearestElement) { - var tp = nearestElement.tooltipPosition(); - x = tp.x; - y = tp.y; - } - - return { - x: x, - y: y - }; - } -}; - -/** - * Helper method to merge the opacity into a color - */ -function mergeOpacity(colorString, opacity) { - var color = helpers.color(colorString); - return color.alpha(opacity * color.alpha()).rgbaString(); -} - -// Helper to push or concat based on if the 2nd parameter is an array or not -function pushOrConcat(base, toPush) { - if (toPush) { - if (helpers.isArray(toPush)) { - // base = base.concat(toPush); - Array.prototype.push.apply(base, toPush); - } else { - base.push(toPush); - } - } - - return base; -} - -/** - * Returns array of strings split by newline - * @param {String} value - The value to split by newline. - * @returns {Array} value if newline present - Returned from String split() method - * @function - */ -function splitNewlines(str) { - if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) { - return str.split('\n'); - } - return str; -} - - -// Private helper to create a tooltip item model -// @param element : the chart element (point, arc, bar) to create the tooltip item for -// @return : new tooltip item -function createTooltipItem(element) { - var xScale = element._xScale; - var yScale = element._yScale || element._scale; // handle radar || polarArea charts - var index = element._index; - var datasetIndex = element._datasetIndex; - - return { - xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '', - yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '', - index: index, - datasetIndex: datasetIndex, - x: element._model.x, - y: element._model.y - }; -} - -/** - * Helper to get the reset model for the tooltip - * @param tooltipOpts {Object} the tooltip options - */ -function getBaseModel(tooltipOpts) { - var globalDefaults = defaults.global; - var valueOrDefault = helpers.valueOrDefault; - - return { - // Positioning - xPadding: tooltipOpts.xPadding, - yPadding: tooltipOpts.yPadding, - xAlign: tooltipOpts.xAlign, - yAlign: tooltipOpts.yAlign, - - // Body - bodyFontColor: tooltipOpts.bodyFontColor, - _bodyFontFamily: valueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily), - _bodyFontStyle: valueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle), - _bodyAlign: tooltipOpts.bodyAlign, - bodyFontSize: valueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize), - bodySpacing: tooltipOpts.bodySpacing, - - // Title - titleFontColor: tooltipOpts.titleFontColor, - _titleFontFamily: valueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily), - _titleFontStyle: valueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle), - titleFontSize: valueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize), - _titleAlign: tooltipOpts.titleAlign, - titleSpacing: tooltipOpts.titleSpacing, - titleMarginBottom: tooltipOpts.titleMarginBottom, - - // Footer - footerFontColor: tooltipOpts.footerFontColor, - _footerFontFamily: valueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily), - _footerFontStyle: valueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle), - footerFontSize: valueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize), - _footerAlign: tooltipOpts.footerAlign, - footerSpacing: tooltipOpts.footerSpacing, - footerMarginTop: tooltipOpts.footerMarginTop, - - // Appearance - caretSize: tooltipOpts.caretSize, - cornerRadius: tooltipOpts.cornerRadius, - backgroundColor: tooltipOpts.backgroundColor, - opacity: 0, - legendColorBackground: tooltipOpts.multiKeyBackground, - displayColors: tooltipOpts.displayColors, - borderColor: tooltipOpts.borderColor, - borderWidth: tooltipOpts.borderWidth - }; -} - -/** - * Get the size of the tooltip - */ -function getTooltipSize(tooltip, model) { - var ctx = tooltip._chart.ctx; - - var height = model.yPadding * 2; // Tooltip Padding - var width = 0; - - // Count of all lines in the body - var body = model.body; - var combinedBodyLength = body.reduce(function(count, bodyItem) { - return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length; - }, 0); - combinedBodyLength += model.beforeBody.length + model.afterBody.length; - - var titleLineCount = model.title.length; - var footerLineCount = model.footer.length; - var titleFontSize = model.titleFontSize; - var bodyFontSize = model.bodyFontSize; - var footerFontSize = model.footerFontSize; - - height += titleLineCount * titleFontSize; // Title Lines - height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing - height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin - height += combinedBodyLength * bodyFontSize; // Body Lines - height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing - height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin - height += footerLineCount * (footerFontSize); // Footer Lines - height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing - - // Title width - var widthPadding = 0; - var maxLineWidth = function(line) { - width = Math.max(width, ctx.measureText(line).width + widthPadding); - }; - - ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily); - helpers.each(model.title, maxLineWidth); - - // Body width - ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily); - helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth); - - // Body lines may include some extra width due to the color box - widthPadding = model.displayColors ? (bodyFontSize + 2) : 0; - helpers.each(body, function(bodyItem) { - helpers.each(bodyItem.before, maxLineWidth); - helpers.each(bodyItem.lines, maxLineWidth); - helpers.each(bodyItem.after, maxLineWidth); - }); - - // Reset back to 0 - widthPadding = 0; - - // Footer width - ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily); - helpers.each(model.footer, maxLineWidth); - - // Add padding - width += 2 * model.xPadding; - - return { - width: width, - height: height - }; -} - -/** - * Helper to get the alignment of a tooltip given the size - */ -function determineAlignment(tooltip, size) { - var model = tooltip._model; - var chart = tooltip._chart; - var chartArea = tooltip._chart.chartArea; - var xAlign = 'center'; - var yAlign = 'center'; - - if (model.y < size.height) { - yAlign = 'top'; - } else if (model.y > (chart.height - size.height)) { - yAlign = 'bottom'; - } - - var lf, rf; // functions to determine left, right alignment - var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart - var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges - var midX = (chartArea.left + chartArea.right) / 2; - var midY = (chartArea.top + chartArea.bottom) / 2; - - if (yAlign === 'center') { - lf = function(x) { - return x <= midX; - }; - rf = function(x) { - return x > midX; - }; - } else { - lf = function(x) { - return x <= (size.width / 2); - }; - rf = function(x) { - return x >= (chart.width - (size.width / 2)); - }; - } - - olf = function(x) { - return x + size.width + model.caretSize + model.caretPadding > chart.width; - }; - orf = function(x) { - return x - size.width - model.caretSize - model.caretPadding < 0; - }; - yf = function(y) { - return y <= midY ? 'top' : 'bottom'; - }; - - if (lf(model.x)) { - xAlign = 'left'; - - // Is tooltip too wide and goes over the right side of the chart.? - if (olf(model.x)) { - xAlign = 'center'; - yAlign = yf(model.y); - } - } else if (rf(model.x)) { - xAlign = 'right'; - - // Is tooltip too wide and goes outside left edge of canvas? - if (orf(model.x)) { - xAlign = 'center'; - yAlign = yf(model.y); - } - } - - var opts = tooltip._options; - return { - xAlign: opts.xAlign ? opts.xAlign : xAlign, - yAlign: opts.yAlign ? opts.yAlign : yAlign - }; -} - -/** - * Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment - */ -function getBackgroundPoint(vm, size, alignment, chart) { - // Background Position - var x = vm.x; - var y = vm.y; - - var caretSize = vm.caretSize; - var caretPadding = vm.caretPadding; - var cornerRadius = vm.cornerRadius; - var xAlign = alignment.xAlign; - var yAlign = alignment.yAlign; - var paddingAndSize = caretSize + caretPadding; - var radiusAndPadding = cornerRadius + caretPadding; - - if (xAlign === 'right') { - x -= size.width; - } else if (xAlign === 'center') { - x -= (size.width / 2); - if (x + size.width > chart.width) { - x = chart.width - size.width; - } - if (x < 0) { - x = 0; - } - } - - if (yAlign === 'top') { - y += paddingAndSize; - } else if (yAlign === 'bottom') { - y -= size.height + paddingAndSize; - } else { - y -= (size.height / 2); - } - - if (yAlign === 'center') { - if (xAlign === 'left') { - x += paddingAndSize; - } else if (xAlign === 'right') { - x -= paddingAndSize; - } - } else if (xAlign === 'left') { - x -= radiusAndPadding; - } else if (xAlign === 'right') { - x += radiusAndPadding; - } - - return { - x: x, - y: y - }; -} - -/** - * Helper to build before and after body lines - */ -function getBeforeAfterBodyLines(callback) { - return pushOrConcat([], splitNewlines(callback)); -} - -var exports = module.exports = Element.extend({ - initialize: function() { - this._model = getBaseModel(this._options); - this._lastActive = []; - }, - - // Get the title - // Args are: (tooltipItem, data) - getTitle: function() { - var me = this; - var opts = me._options; - var callbacks = opts.callbacks; - - var beforeTitle = callbacks.beforeTitle.apply(me, arguments); - var title = callbacks.title.apply(me, arguments); - var afterTitle = callbacks.afterTitle.apply(me, arguments); - - var lines = []; - lines = pushOrConcat(lines, splitNewlines(beforeTitle)); - lines = pushOrConcat(lines, splitNewlines(title)); - lines = pushOrConcat(lines, splitNewlines(afterTitle)); - - return lines; - }, - - // Args are: (tooltipItem, data) - getBeforeBody: function() { - return getBeforeAfterBodyLines(this._options.callbacks.beforeBody.apply(this, arguments)); - }, - - // Args are: (tooltipItem, data) - getBody: function(tooltipItems, data) { - var me = this; - var callbacks = me._options.callbacks; - var bodyItems = []; - - helpers.each(tooltipItems, function(tooltipItem) { - var bodyItem = { - before: [], - lines: [], - after: [] - }; - pushOrConcat(bodyItem.before, splitNewlines(callbacks.beforeLabel.call(me, tooltipItem, data))); - pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data)); - pushOrConcat(bodyItem.after, splitNewlines(callbacks.afterLabel.call(me, tooltipItem, data))); - - bodyItems.push(bodyItem); - }); - - return bodyItems; - }, - - // Args are: (tooltipItem, data) - getAfterBody: function() { - return getBeforeAfterBodyLines(this._options.callbacks.afterBody.apply(this, arguments)); - }, - - // Get the footer and beforeFooter and afterFooter lines - // Args are: (tooltipItem, data) - getFooter: function() { - var me = this; - var callbacks = me._options.callbacks; - - var beforeFooter = callbacks.beforeFooter.apply(me, arguments); - var footer = callbacks.footer.apply(me, arguments); - var afterFooter = callbacks.afterFooter.apply(me, arguments); - - var lines = []; - lines = pushOrConcat(lines, splitNewlines(beforeFooter)); - lines = pushOrConcat(lines, splitNewlines(footer)); - lines = pushOrConcat(lines, splitNewlines(afterFooter)); - - return lines; - }, - - update: function(changed) { - var me = this; - var opts = me._options; - - // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition - // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time - // which breaks any animations. - var existingModel = me._model; - var model = me._model = getBaseModel(opts); - var active = me._active; - - var data = me._data; - - // In the case where active.length === 0 we need to keep these at existing values for good animations - var alignment = { - xAlign: existingModel.xAlign, - yAlign: existingModel.yAlign - }; - var backgroundPoint = { - x: existingModel.x, - y: existingModel.y - }; - var tooltipSize = { - width: existingModel.width, - height: existingModel.height - }; - var tooltipPosition = { - x: existingModel.caretX, - y: existingModel.caretY - }; - - var i, len; - - if (active.length) { - model.opacity = 1; - - var labelColors = []; - var labelTextColors = []; - tooltipPosition = positioners[opts.position].call(me, active, me._eventPosition); - - var tooltipItems = []; - for (i = 0, len = active.length; i < len; ++i) { - tooltipItems.push(createTooltipItem(active[i])); - } - - // If the user provided a filter function, use it to modify the tooltip items - if (opts.filter) { - tooltipItems = tooltipItems.filter(function(a) { - return opts.filter(a, data); - }); - } - - // If the user provided a sorting function, use it to modify the tooltip items - if (opts.itemSort) { - tooltipItems = tooltipItems.sort(function(a, b) { - return opts.itemSort(a, b, data); - }); - } - - // Determine colors for boxes - helpers.each(tooltipItems, function(tooltipItem) { - labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart)); - labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart)); - }); - - - // Build the Text Lines - model.title = me.getTitle(tooltipItems, data); - model.beforeBody = me.getBeforeBody(tooltipItems, data); - model.body = me.getBody(tooltipItems, data); - model.afterBody = me.getAfterBody(tooltipItems, data); - model.footer = me.getFooter(tooltipItems, data); - - // Initial positioning and colors - model.x = Math.round(tooltipPosition.x); - model.y = Math.round(tooltipPosition.y); - model.caretPadding = opts.caretPadding; - model.labelColors = labelColors; - model.labelTextColors = labelTextColors; - - // data points - model.dataPoints = tooltipItems; - - // We need to determine alignment of the tooltip - tooltipSize = getTooltipSize(this, model); - alignment = determineAlignment(this, tooltipSize); - // Final Size and Position - backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart); - } else { - model.opacity = 0; - } - - model.xAlign = alignment.xAlign; - model.yAlign = alignment.yAlign; - model.x = backgroundPoint.x; - model.y = backgroundPoint.y; - model.width = tooltipSize.width; - model.height = tooltipSize.height; - - // Point where the caret on the tooltip points to - model.caretX = tooltipPosition.x; - model.caretY = tooltipPosition.y; - - me._model = model; - - if (changed && opts.custom) { - opts.custom.call(me, model); - } - - return me; - }, - - drawCaret: function(tooltipPoint, size) { - var ctx = this._chart.ctx; - var vm = this._view; - var caretPosition = this.getCaretPosition(tooltipPoint, size, vm); - - ctx.lineTo(caretPosition.x1, caretPosition.y1); - ctx.lineTo(caretPosition.x2, caretPosition.y2); - ctx.lineTo(caretPosition.x3, caretPosition.y3); - }, - getCaretPosition: function(tooltipPoint, size, vm) { - var x1, x2, x3, y1, y2, y3; - var caretSize = vm.caretSize; - var cornerRadius = vm.cornerRadius; - var xAlign = vm.xAlign; - var yAlign = vm.yAlign; - var ptX = tooltipPoint.x; - var ptY = tooltipPoint.y; - var width = size.width; - var height = size.height; - - if (yAlign === 'center') { - y2 = ptY + (height / 2); - - if (xAlign === 'left') { - x1 = ptX; - x2 = x1 - caretSize; - x3 = x1; - - y1 = y2 + caretSize; - y3 = y2 - caretSize; - } else { - x1 = ptX + width; - x2 = x1 + caretSize; - x3 = x1; - - y1 = y2 - caretSize; - y3 = y2 + caretSize; - } - } else { - if (xAlign === 'left') { - x2 = ptX + cornerRadius + (caretSize); - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } else if (xAlign === 'right') { - x2 = ptX + width - cornerRadius - caretSize; - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } else { - x2 = vm.caretX; - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } - if (yAlign === 'top') { - y1 = ptY; - y2 = y1 - caretSize; - y3 = y1; - } else { - y1 = ptY + height; - y2 = y1 + caretSize; - y3 = y1; - // invert drawing order - var tmp = x3; - x3 = x1; - x1 = tmp; - } - } - return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3}; - }, - - drawTitle: function(pt, vm, ctx, opacity) { - var title = vm.title; - - if (title.length) { - ctx.textAlign = vm._titleAlign; - ctx.textBaseline = 'top'; - - var titleFontSize = vm.titleFontSize; - var titleSpacing = vm.titleSpacing; - - ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity); - ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily); - - var i, len; - for (i = 0, len = title.length; i < len; ++i) { - ctx.fillText(title[i], pt.x, pt.y); - pt.y += titleFontSize + titleSpacing; // Line Height and spacing - - if (i + 1 === title.length) { - pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing - } - } - } - }, - - drawBody: function(pt, vm, ctx, opacity) { - var bodyFontSize = vm.bodyFontSize; - var bodySpacing = vm.bodySpacing; - var body = vm.body; - - ctx.textAlign = vm._bodyAlign; - ctx.textBaseline = 'top'; - ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily); - - // Before Body - var xLinePadding = 0; - var fillLineOfText = function(line) { - ctx.fillText(line, pt.x + xLinePadding, pt.y); - pt.y += bodyFontSize + bodySpacing; - }; - - // Before body lines - ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity); - helpers.each(vm.beforeBody, fillLineOfText); - - var drawColorBoxes = vm.displayColors; - xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0; - - // Draw body lines now - helpers.each(body, function(bodyItem, i) { - var textColor = mergeOpacity(vm.labelTextColors[i], opacity); - ctx.fillStyle = textColor; - helpers.each(bodyItem.before, fillLineOfText); - - helpers.each(bodyItem.lines, function(line) { - // Draw Legend-like boxes if needed - if (drawColorBoxes) { - // Fill a white rect so that colours merge nicely if the opacity is < 1 - ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity); - ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize); - - // Border - ctx.lineWidth = 1; - ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity); - ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize); - - // Inner square - ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity); - ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2); - ctx.fillStyle = textColor; - } - - fillLineOfText(line); - }); - - helpers.each(bodyItem.after, fillLineOfText); - }); - - // Reset back to 0 for after body - xLinePadding = 0; - - // After body lines - helpers.each(vm.afterBody, fillLineOfText); - pt.y -= bodySpacing; // Remove last body spacing - }, - - drawFooter: function(pt, vm, ctx, opacity) { - var footer = vm.footer; - - if (footer.length) { - pt.y += vm.footerMarginTop; - - ctx.textAlign = vm._footerAlign; - ctx.textBaseline = 'top'; - - ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity); - ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily); - - helpers.each(footer, function(line) { - ctx.fillText(line, pt.x, pt.y); - pt.y += vm.footerFontSize + vm.footerSpacing; - }); - } - }, - - drawBackground: function(pt, vm, ctx, tooltipSize, opacity) { - ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity); - ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity); - ctx.lineWidth = vm.borderWidth; - var xAlign = vm.xAlign; - var yAlign = vm.yAlign; - var x = pt.x; - var y = pt.y; - var width = tooltipSize.width; - var height = tooltipSize.height; - var radius = vm.cornerRadius; - - ctx.beginPath(); - ctx.moveTo(x + radius, y); - if (yAlign === 'top') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - if (yAlign === 'center' && xAlign === 'right') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - if (yAlign === 'bottom') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - if (yAlign === 'center' && xAlign === 'left') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - - ctx.fill(); - - if (vm.borderWidth > 0) { - ctx.stroke(); - } - }, - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - - if (vm.opacity === 0) { - return; - } - - var tooltipSize = { - width: vm.width, - height: vm.height - }; - var pt = { - x: vm.x, - y: vm.y - }; - - // IE11/Edge does not like very small opacities, so snap to 0 - var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity; - - // Truthy/falsey value for empty tooltip - var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length; - - if (this._options.enabled && hasTooltipContent) { - // Draw Background - this.drawBackground(pt, vm, ctx, tooltipSize, opacity); - - // Draw Title, Body, and Footer - pt.x += vm.xPadding; - pt.y += vm.yPadding; - - // Titles - this.drawTitle(pt, vm, ctx, opacity); - - // Body - this.drawBody(pt, vm, ctx, opacity); - - // Footer - this.drawFooter(pt, vm, ctx, opacity); - } - }, - - /** - * Handle an event - * @private - * @param {IEvent} event - The event to handle - * @returns {Boolean} true if the tooltip changed - */ - handleEvent: function(e) { - var me = this; - var options = me._options; - var changed = false; - - me._lastActive = me._lastActive || []; - - // Find Active Elements for tooltips - if (e.type === 'mouseout') { - me._active = []; - } else { - me._active = me._chart.getElementsAtEventForMode(e, options.mode, options); - } - - // Remember Last Actives - changed = !helpers.arrayEquals(me._active, me._lastActive); - - // Only handle target event on tooltip change - if (changed) { - me._lastActive = me._active; - - if (options.enabled || options.custom) { - me._eventPosition = { - x: e.x, - y: e.y - }; - - me.update(true); - me.pivot(); - } - } - - return changed; - } -}); - -/** - * @namespace Chart.Tooltip.positioners - */ -exports.positioners = positioners; - - -},{"26":26,"27":27,"46":46}],37:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); - -defaults._set('global', { - elements: { - arc: { - backgroundColor: defaults.global.defaultColor, - borderColor: '#fff', - borderWidth: 2 - } - } -}); - -module.exports = Element.extend({ - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); - } - return false; - }, - - inRange: function(chartX, chartY) { - var vm = this._view; - - if (vm) { - var pointRelativePosition = helpers.getAngleFromPoint(vm, {x: chartX, y: chartY}); - var angle = pointRelativePosition.angle; - var distance = pointRelativePosition.distance; - - // Sanitise angle range - var startAngle = vm.startAngle; - var endAngle = vm.endAngle; - while (endAngle < startAngle) { - endAngle += 2.0 * Math.PI; - } - while (angle > endAngle) { - angle -= 2.0 * Math.PI; - } - while (angle < startAngle) { - angle += 2.0 * Math.PI; - } - - // Check if within the range of the open/close angle - var betweenAngles = (angle >= startAngle && angle <= endAngle); - var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); - - return (betweenAngles && withinRadius); - } - return false; - }, - - getCenterPoint: function() { - var vm = this._view; - var halfAngle = (vm.startAngle + vm.endAngle) / 2; - var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; - return { - x: vm.x + Math.cos(halfAngle) * halfRadius, - y: vm.y + Math.sin(halfAngle) * halfRadius - }; - }, - - getArea: function() { - var vm = this._view; - return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); - }, - - tooltipPosition: function() { - var vm = this._view; - var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); - var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; - - return { - x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), - y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) - }; - }, - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var sA = vm.startAngle; - var eA = vm.endAngle; - - ctx.beginPath(); - - ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA); - ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); - - ctx.closePath(); - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - ctx.fillStyle = vm.backgroundColor; - - ctx.fill(); - ctx.lineJoin = 'bevel'; - - if (vm.borderWidth) { - ctx.stroke(); - } - } -}); - -},{"26":26,"27":27,"46":46}],38:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); - -var globalDefaults = defaults.global; - -defaults._set('global', { - elements: { - line: { - tension: 0.4, - backgroundColor: globalDefaults.defaultColor, - borderWidth: 3, - borderColor: globalDefaults.defaultColor, - borderCapStyle: 'butt', - borderDash: [], - borderDashOffset: 0.0, - borderJoinStyle: 'miter', - capBezierPoints: true, - fill: true, // do we fill in the area between the line and its base axis - } - } -}); - -module.exports = Element.extend({ - draw: function() { - var me = this; - var vm = me._view; - var ctx = me._chart.ctx; - var spanGaps = vm.spanGaps; - var points = me._children.slice(); // clone array - var globalOptionLineElements = globalDefaults.elements.line; - var lastDrawnIndex = -1; - var index, current, previous, currentVM; - - // If we are looping, adding the first point again - if (me._loop && points.length) { - points.push(points[0]); - } - - ctx.save(); - - // Stroke Line Options - ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; - - // IE 9 and 10 do not support line dash - if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); - } - - ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset; - ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; - ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth; - ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; - - // Stroke Line - ctx.beginPath(); - lastDrawnIndex = -1; - - for (index = 0; index < points.length; ++index) { - current = points[index]; - previous = helpers.previousItem(points, index); - currentVM = current._view; - - // First point moves to it's starting position no matter what - if (index === 0) { - if (!currentVM.skip) { - ctx.moveTo(currentVM.x, currentVM.y); - lastDrawnIndex = index; - } - } else { - previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex]; - - if (!currentVM.skip) { - if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { - // There was a gap and this is the first point after the gap - ctx.moveTo(currentVM.x, currentVM.y); - } else { - // Line to next point - helpers.canvas.lineTo(ctx, previous._view, current._view); - } - lastDrawnIndex = index; - } - } - } - - ctx.stroke(); - ctx.restore(); - } -}); - -},{"26":26,"27":27,"46":46}],39:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); - -var defaultColor = defaults.global.defaultColor; - -defaults._set('global', { - elements: { - point: { - radius: 3, - pointStyle: 'circle', - backgroundColor: defaultColor, - borderColor: defaultColor, - borderWidth: 1, - // Hover - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1 - } - } -}); - -function xRange(mouseX) { - var vm = this._view; - return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; -} - -function yRange(mouseY) { - var vm = this._view; - return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; -} - -module.exports = Element.extend({ - inRange: function(mouseX, mouseY) { - var vm = this._view; - return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; - }, - - inLabelRange: xRange, - inXRange: xRange, - inYRange: yRange, - - getCenterPoint: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - }, - - getArea: function() { - return Math.PI * Math.pow(this._view.radius, 2); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y, - padding: vm.radius + vm.borderWidth - }; - }, - - draw: function(chartArea) { - var vm = this._view; - var model = this._model; - var ctx = this._chart.ctx; - var pointStyle = vm.pointStyle; - var rotation = vm.rotation; - var radius = vm.radius; - var x = vm.x; - var y = vm.y; - var errMargin = 1.01; // 1.01 is margin for Accumulated error. (Especially Edge, IE.) - - if (vm.skip) { - return; - } - - // Clipping for Points. - if (chartArea === undefined || (model.x >= chartArea.left && chartArea.right * errMargin >= model.x && model.y >= chartArea.top && chartArea.bottom * errMargin >= model.y)) { - ctx.strokeStyle = vm.borderColor || defaultColor; - ctx.lineWidth = helpers.valueOrDefault(vm.borderWidth, defaults.global.elements.point.borderWidth); - ctx.fillStyle = vm.backgroundColor || defaultColor; - helpers.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation); - } - } -}); - -},{"26":26,"27":27,"46":46}],40:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); - -defaults._set('global', { - elements: { - rectangle: { - backgroundColor: defaults.global.defaultColor, - borderColor: defaults.global.defaultColor, - borderSkipped: 'bottom', - borderWidth: 0 - } - } -}); - -function isVertical(bar) { - return bar._view.width !== undefined; -} - -/** - * Helper function to get the bounds of the bar regardless of the orientation - * @param bar {Chart.Element.Rectangle} the bar - * @return {Bounds} bounds of the bar - * @private - */ -function getBarBounds(bar) { - var vm = bar._view; - var x1, x2, y1, y2; - - if (isVertical(bar)) { - // vertical - var halfWidth = vm.width / 2; - x1 = vm.x - halfWidth; - x2 = vm.x + halfWidth; - y1 = Math.min(vm.y, vm.base); - y2 = Math.max(vm.y, vm.base); - } else { - // horizontal bar - var halfHeight = vm.height / 2; - x1 = Math.min(vm.x, vm.base); - x2 = Math.max(vm.x, vm.base); - y1 = vm.y - halfHeight; - y2 = vm.y + halfHeight; - } - - return { - left: x1, - top: y1, - right: x2, - bottom: y2 - }; -} - -module.exports = Element.extend({ - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var left, right, top, bottom, signX, signY, borderSkipped; - var borderWidth = vm.borderWidth; - - if (!vm.horizontal) { - // bar - left = vm.x - vm.width / 2; - right = vm.x + vm.width / 2; - top = vm.y; - bottom = vm.base; - signX = 1; - signY = bottom > top ? 1 : -1; - borderSkipped = vm.borderSkipped || 'bottom'; - } else { - // horizontal bar - left = vm.base; - right = vm.x; - top = vm.y - vm.height / 2; - bottom = vm.y + vm.height / 2; - signX = right > left ? 1 : -1; - signY = 1; - borderSkipped = vm.borderSkipped || 'left'; - } - - // Canvas doesn't allow us to stroke inside the width so we can - // adjust the sizes to fit if we're setting a stroke on the line - if (borderWidth) { - // borderWidth shold be less than bar width and bar height. - var barSize = Math.min(Math.abs(left - right), Math.abs(top - bottom)); - borderWidth = borderWidth > barSize ? barSize : borderWidth; - var halfStroke = borderWidth / 2; - // Adjust borderWidth when bar top position is near vm.base(zero). - var borderLeft = left + (borderSkipped !== 'left' ? halfStroke * signX : 0); - var borderRight = right + (borderSkipped !== 'right' ? -halfStroke * signX : 0); - var borderTop = top + (borderSkipped !== 'top' ? halfStroke * signY : 0); - var borderBottom = bottom + (borderSkipped !== 'bottom' ? -halfStroke * signY : 0); - // not become a vertical line? - if (borderLeft !== borderRight) { - top = borderTop; - bottom = borderBottom; - } - // not become a horizontal line? - if (borderTop !== borderBottom) { - left = borderLeft; - right = borderRight; - } - } - - ctx.beginPath(); - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = borderWidth; - - // Corner points, from bottom-left to bottom-right clockwise - // | 1 2 | - // | 0 3 | - var corners = [ - [left, bottom], - [left, top], - [right, top], - [right, bottom] - ]; - - // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; - var startCorner = borders.indexOf(borderSkipped, 0); - if (startCorner === -1) { - startCorner = 0; - } - - function cornerAt(index) { - return corners[(startCorner + index) % 4]; - } - - // Draw rectangle from 'startCorner' - var corner = cornerAt(0); - ctx.moveTo(corner[0], corner[1]); - - for (var i = 1; i < 4; i++) { - corner = cornerAt(i); - ctx.lineTo(corner[0], corner[1]); - } - - ctx.fill(); - if (borderWidth) { - ctx.stroke(); - } - }, - - height: function() { - var vm = this._view; - return vm.base - vm.y; - }, - - inRange: function(mouseX, mouseY) { - var inRange = false; - - if (this._view) { - var bounds = getBarBounds(this); - inRange = mouseX >= bounds.left && mouseX <= bounds.right && mouseY >= bounds.top && mouseY <= bounds.bottom; - } - - return inRange; - }, - - inLabelRange: function(mouseX, mouseY) { - var me = this; - if (!me._view) { - return false; - } - - var inRange = false; - var bounds = getBarBounds(me); - - if (isVertical(me)) { - inRange = mouseX >= bounds.left && mouseX <= bounds.right; - } else { - inRange = mouseY >= bounds.top && mouseY <= bounds.bottom; - } - - return inRange; - }, - - inXRange: function(mouseX) { - var bounds = getBarBounds(this); - return mouseX >= bounds.left && mouseX <= bounds.right; - }, - - inYRange: function(mouseY) { - var bounds = getBarBounds(this); - return mouseY >= bounds.top && mouseY <= bounds.bottom; - }, - - getCenterPoint: function() { - var vm = this._view; - var x, y; - if (isVertical(this)) { - x = vm.x; - y = (vm.y + vm.base) / 2; - } else { - x = (vm.x + vm.base) / 2; - y = vm.y; - } - - return {x: x, y: y}; - }, - - getArea: function() { - var vm = this._view; - return vm.width * Math.abs(vm.y - vm.base); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - } -}); - -},{"26":26,"27":27}],41:[function(require,module,exports){ -'use strict'; - -module.exports = {}; -module.exports.Arc = require(37); -module.exports.Line = require(38); -module.exports.Point = require(39); -module.exports.Rectangle = require(40); - -},{"37":37,"38":38,"39":39,"40":40}],42:[function(require,module,exports){ -'use strict'; - -var helpers = require(43); - -/** - * @namespace Chart.helpers.canvas - */ -var exports = module.exports = { - /** - * Clears the entire canvas associated to the given `chart`. - * @param {Chart} chart - The chart for which to clear the canvas. - */ - clear: function(chart) { - chart.ctx.clearRect(0, 0, chart.width, chart.height); - }, - - /** - * Creates a "path" for a rectangle with rounded corners at position (x, y) with a - * given size (width, height) and the same `radius` for all corners. - * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. - * @param {Number} x - The x axis of the coordinate for the rectangle starting point. - * @param {Number} y - The y axis of the coordinate for the rectangle starting point. - * @param {Number} width - The rectangle's width. - * @param {Number} height - The rectangle's height. - * @param {Number} radius - The rounded amount (in pixels) for the four corners. - * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? - */ - roundedRect: function(ctx, x, y, width, height, radius) { - if (radius) { - // NOTE(SB) `epsilon` helps to prevent minor artifacts appearing - // on Chrome when `r` is exactly half the height or the width. - var epsilon = 0.0000001; - var r = Math.min(radius, (height / 2) - epsilon, (width / 2) - epsilon); - - ctx.moveTo(x + r, y); - ctx.lineTo(x + width - r, y); - ctx.arcTo(x + width, y, x + width, y + r, r); - ctx.lineTo(x + width, y + height - r); - ctx.arcTo(x + width, y + height, x + width - r, y + height, r); - ctx.lineTo(x + r, y + height); - ctx.arcTo(x, y + height, x, y + height - r, r); - ctx.lineTo(x, y + r); - ctx.arcTo(x, y, x + r, y, r); - ctx.closePath(); - ctx.moveTo(x, y); - } else { - ctx.rect(x, y, width, height); - } - }, - - drawPoint: function(ctx, style, radius, x, y, rotation) { - var type, edgeLength, xOffset, yOffset, height, size; - rotation = rotation || 0; - - if (style && typeof style === 'object') { - type = style.toString(); - if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { - ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height); - return; - } - } - - if (isNaN(radius) || radius <= 0) { - return; - } - - ctx.save(); - ctx.translate(x, y); - ctx.rotate(rotation * Math.PI / 180); - ctx.beginPath(); - - switch (style) { - // Default includes circle - default: - ctx.arc(0, 0, radius, 0, Math.PI * 2); - ctx.closePath(); - break; - case 'triangle': - edgeLength = 3 * radius / Math.sqrt(3); - height = edgeLength * Math.sqrt(3) / 2; - ctx.moveTo(-edgeLength / 2, height / 3); - ctx.lineTo(edgeLength / 2, height / 3); - ctx.lineTo(0, -2 * height / 3); - ctx.closePath(); - break; - case 'rect': - size = 1 / Math.SQRT2 * radius; - ctx.rect(-size, -size, 2 * size, 2 * size); - break; - case 'rectRounded': - var offset = radius / Math.SQRT2; - var leftX = -offset; - var topY = -offset; - var sideSize = Math.SQRT2 * radius; - - // NOTE(SB) the rounded rect implementation changed to use `arcTo` - // instead of `quadraticCurveTo` since it generates better results - // when rect is almost a circle. 0.425 (instead of 0.5) produces - // results visually closer to the previous impl. - this.roundedRect(ctx, leftX, topY, sideSize, sideSize, radius * 0.425); - break; - case 'rectRot': - size = 1 / Math.SQRT2 * radius; - ctx.moveTo(-size, 0); - ctx.lineTo(0, size); - ctx.lineTo(size, 0); - ctx.lineTo(0, -size); - ctx.closePath(); - break; - case 'cross': - ctx.moveTo(0, radius); - ctx.lineTo(0, -radius); - ctx.moveTo(-radius, 0); - ctx.lineTo(radius, 0); - break; - case 'crossRot': - xOffset = Math.cos(Math.PI / 4) * radius; - yOffset = Math.sin(Math.PI / 4) * radius; - ctx.moveTo(-xOffset, -yOffset); - ctx.lineTo(xOffset, yOffset); - ctx.moveTo(-xOffset, yOffset); - ctx.lineTo(xOffset, -yOffset); - break; - case 'star': - ctx.moveTo(0, radius); - ctx.lineTo(0, -radius); - ctx.moveTo(-radius, 0); - ctx.lineTo(radius, 0); - xOffset = Math.cos(Math.PI / 4) * radius; - yOffset = Math.sin(Math.PI / 4) * radius; - ctx.moveTo(-xOffset, -yOffset); - ctx.lineTo(xOffset, yOffset); - ctx.moveTo(-xOffset, yOffset); - ctx.lineTo(xOffset, -yOffset); - break; - case 'line': - ctx.moveTo(-radius, 0); - ctx.lineTo(radius, 0); - break; - case 'dash': - ctx.moveTo(0, 0); - ctx.lineTo(radius, 0); - break; - } - - ctx.fill(); - ctx.stroke(); - ctx.restore(); - }, - - clipArea: function(ctx, area) { - ctx.save(); - ctx.beginPath(); - ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); - ctx.clip(); - }, - - unclipArea: function(ctx) { - ctx.restore(); - }, - - lineTo: function(ctx, previous, target, flip) { - if (target.steppedLine) { - if ((target.steppedLine === 'after' && !flip) || (target.steppedLine !== 'after' && flip)) { - ctx.lineTo(previous.x, target.y); - } else { - ctx.lineTo(target.x, previous.y); - } - ctx.lineTo(target.x, target.y); - return; - } - - if (!target.tension) { - ctx.lineTo(target.x, target.y); - return; - } - - ctx.bezierCurveTo( - flip ? previous.controlPointPreviousX : previous.controlPointNextX, - flip ? previous.controlPointPreviousY : previous.controlPointNextY, - flip ? target.controlPointNextX : target.controlPointPreviousX, - flip ? target.controlPointNextY : target.controlPointPreviousY, - target.x, - target.y); - } -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. - * @namespace Chart.helpers.clear - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.clear = exports.clear; - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. - * @namespace Chart.helpers.drawRoundedRectangle - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.drawRoundedRectangle = function(ctx) { - ctx.beginPath(); - exports.roundedRect.apply(exports, arguments); -}; - -},{"43":43}],43:[function(require,module,exports){ -'use strict'; - -/** - * @namespace Chart.helpers - */ -var helpers = { - /** - * An empty function that can be used, for example, for optional callback. - */ - noop: function() {}, - - /** - * Returns a unique id, sequentially generated from a global variable. - * @returns {Number} - * @function - */ - uid: (function() { - var id = 0; - return function() { - return id++; - }; - }()), - - /** - * Returns true if `value` is neither null nor undefined, else returns false. - * @param {*} value - The value to test. - * @returns {Boolean} - * @since 2.7.0 - */ - isNullOrUndef: function(value) { - return value === null || typeof value === 'undefined'; - }, - - /** - * Returns true if `value` is an array, else returns false. - * @param {*} value - The value to test. - * @returns {Boolean} - * @function - */ - isArray: Array.isArray ? Array.isArray : function(value) { - return Object.prototype.toString.call(value) === '[object Array]'; - }, - - /** - * Returns true if `value` is an object (excluding null), else returns false. - * @param {*} value - The value to test. - * @returns {Boolean} - * @since 2.7.0 - */ - isObject: function(value) { - return value !== null && Object.prototype.toString.call(value) === '[object Object]'; - }, - - /** - * Returns `value` if defined, else returns `defaultValue`. - * @param {*} value - The value to return if defined. - * @param {*} defaultValue - The value to return if `value` is undefined. - * @returns {*} - */ - valueOrDefault: function(value, defaultValue) { - return typeof value === 'undefined' ? defaultValue : value; - }, - - /** - * Returns value at the given `index` in array if defined, else returns `defaultValue`. - * @param {Array} value - The array to lookup for value at `index`. - * @param {Number} index - The index in `value` to lookup for value. - * @param {*} defaultValue - The value to return if `value[index]` is undefined. - * @returns {*} - */ - valueAtIndexOrDefault: function(value, index, defaultValue) { - return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); - }, - - /** - * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the - * value returned by `fn`. If `fn` is not a function, this method returns undefined. - * @param {Function} fn - The function to call. - * @param {Array|undefined|null} args - The arguments with which `fn` should be called. - * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`. - * @returns {*} - */ - callback: function(fn, args, thisArg) { - if (fn && typeof fn.call === 'function') { - return fn.apply(thisArg, args); - } - }, - - /** - * Note(SB) for performance sake, this method should only be used when loopable type - * is unknown or in none intensive code (not called often and small loopable). Else - * it's preferable to use a regular for() loop and save extra function calls. - * @param {Object|Array} loopable - The object or array to be iterated. - * @param {Function} fn - The function to call for each item. - * @param {Object} [thisArg] - The value of `this` provided for the call to `fn`. - * @param {Boolean} [reverse] - If true, iterates backward on the loopable. - */ - each: function(loopable, fn, thisArg, reverse) { - var i, len, keys; - if (helpers.isArray(loopable)) { - len = loopable.length; - if (reverse) { - for (i = len - 1; i >= 0; i--) { - fn.call(thisArg, loopable[i], i); - } - } else { - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[i], i); - } - } - } else if (helpers.isObject(loopable)) { - keys = Object.keys(loopable); - len = keys.length; - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[keys[i]], keys[i]); - } - } - }, - - /** - * Returns true if the `a0` and `a1` arrays have the same content, else returns false. - * @see http://stackoverflow.com/a/14853974 - * @param {Array} a0 - The array to compare - * @param {Array} a1 - The array to compare - * @returns {Boolean} - */ - arrayEquals: function(a0, a1) { - var i, ilen, v0, v1; - - if (!a0 || !a1 || a0.length !== a1.length) { - return false; - } - - for (i = 0, ilen = a0.length; i < ilen; ++i) { - v0 = a0[i]; - v1 = a1[i]; - - if (v0 instanceof Array && v1 instanceof Array) { - if (!helpers.arrayEquals(v0, v1)) { - return false; - } - } else if (v0 !== v1) { - // NOTE: two different object instances will never be equal: {x:20} != {x:20} - return false; - } - } - - return true; - }, - - /** - * Returns a deep copy of `source` without keeping references on objects and arrays. - * @param {*} source - The value to clone. - * @returns {*} - */ - clone: function(source) { - if (helpers.isArray(source)) { - return source.map(helpers.clone); - } - - if (helpers.isObject(source)) { - var target = {}; - var keys = Object.keys(source); - var klen = keys.length; - var k = 0; - - for (; k < klen; ++k) { - target[keys[k]] = helpers.clone(source[keys[k]]); - } - - return target; - } - - return source; - }, - - /** - * The default merger when Chart.helpers.merge is called without merger option. - * Note(SB): this method is also used by configMerge and scaleMerge as fallback. - * @private - */ - _merger: function(key, target, source, options) { - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.merge(tval, sval, options); - } else { - target[key] = helpers.clone(sval); - } - }, - - /** - * Merges source[key] in target[key] only if target[key] is undefined. - * @private - */ - _mergerIf: function(key, target, source) { - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.mergeIf(tval, sval); - } else if (!target.hasOwnProperty(key)) { - target[key] = helpers.clone(sval); - } - }, - - /** - * Recursively deep copies `source` properties into `target` with the given `options`. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {Object} target - The target object in which all sources are merged into. - * @param {Object|Array(Object)} source - Object(s) to merge into `target`. - * @param {Object} [options] - Merging options: - * @param {Function} [options.merger] - The merge method (key, target, source, options) - * @returns {Object} The `target` object. - */ - merge: function(target, source, options) { - var sources = helpers.isArray(source) ? source : [source]; - var ilen = sources.length; - var merge, i, keys, klen, k; - - if (!helpers.isObject(target)) { - return target; - } - - options = options || {}; - merge = options.merger || helpers._merger; - - for (i = 0; i < ilen; ++i) { - source = sources[i]; - if (!helpers.isObject(source)) { - continue; - } - - keys = Object.keys(source); - for (k = 0, klen = keys.length; k < klen; ++k) { - merge(keys[k], target, source, options); - } - } - - return target; - }, - - /** - * Recursively deep copies `source` properties into `target` *only* if not defined in target. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {Object} target - The target object in which all sources are merged into. - * @param {Object|Array(Object)} source - Object(s) to merge into `target`. - * @returns {Object} The `target` object. - */ - mergeIf: function(target, source) { - return helpers.merge(target, source, {merger: helpers._mergerIf}); - }, - - /** - * Applies the contents of two or more objects together into the first object. - * @param {Object} target - The target object in which all objects are merged into. - * @param {Object} arg1 - Object containing additional properties to merge in target. - * @param {Object} argN - Additional objects containing properties to merge in target. - * @returns {Object} The `target` object. - */ - extend: function(target) { - var setFn = function(value, key) { - target[key] = value; - }; - for (var i = 1, ilen = arguments.length; i < ilen; ++i) { - helpers.each(arguments[i], setFn); - } - return target; - }, - - /** - * Basic javascript inheritance based on the model created in Backbone.js - */ - inherits: function(extensions) { - var me = this; - var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { - return me.apply(this, arguments); - }; - - var Surrogate = function() { - this.constructor = ChartElement; - }; - - Surrogate.prototype = me.prototype; - ChartElement.prototype = new Surrogate(); - ChartElement.extend = helpers.inherits; - - if (extensions) { - helpers.extend(ChartElement.prototype, extensions); - } - - ChartElement.__super__ = me.prototype; - return ChartElement; - } -}; - -module.exports = helpers; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.callback instead. - * @function Chart.helpers.callCallback - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ -helpers.callCallback = helpers.callback; - -/** - * Provided for backward compatibility, use Array.prototype.indexOf instead. - * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ - * @function Chart.helpers.indexOf - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.indexOf = function(array, item, fromIndex) { - return Array.prototype.indexOf.call(array, item, fromIndex); -}; - -/** - * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. - * @function Chart.helpers.getValueOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueOrDefault = helpers.valueOrDefault; - -/** - * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. - * @function Chart.helpers.getValueAtIndexOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - -},{}],44:[function(require,module,exports){ -'use strict'; - -var helpers = require(43); - -/** - * Easing functions adapted from Robert Penner's easing equations. - * @namespace Chart.helpers.easingEffects - * @see http://www.robertpenner.com/easing/ - */ -var effects = { - linear: function(t) { - return t; - }, - - easeInQuad: function(t) { - return t * t; - }, - - easeOutQuad: function(t) { - return -t * (t - 2); - }, - - easeInOutQuad: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t; - } - return -0.5 * ((--t) * (t - 2) - 1); - }, - - easeInCubic: function(t) { - return t * t * t; - }, - - easeOutCubic: function(t) { - return (t = t - 1) * t * t + 1; - }, - - easeInOutCubic: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t; - } - return 0.5 * ((t -= 2) * t * t + 2); - }, - - easeInQuart: function(t) { - return t * t * t * t; - }, - - easeOutQuart: function(t) { - return -((t = t - 1) * t * t * t - 1); - }, - - easeInOutQuart: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t; - } - return -0.5 * ((t -= 2) * t * t * t - 2); - }, - - easeInQuint: function(t) { - return t * t * t * t * t; - }, - - easeOutQuint: function(t) { - return (t = t - 1) * t * t * t * t + 1; - }, - - easeInOutQuint: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t * t; - } - return 0.5 * ((t -= 2) * t * t * t * t + 2); - }, - - easeInSine: function(t) { - return -Math.cos(t * (Math.PI / 2)) + 1; - }, - - easeOutSine: function(t) { - return Math.sin(t * (Math.PI / 2)); - }, - - easeInOutSine: function(t) { - return -0.5 * (Math.cos(Math.PI * t) - 1); - }, - - easeInExpo: function(t) { - return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); - }, - - easeOutExpo: function(t) { - return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; - }, - - easeInOutExpo: function(t) { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if ((t /= 0.5) < 1) { - return 0.5 * Math.pow(2, 10 * (t - 1)); - } - return 0.5 * (-Math.pow(2, -10 * --t) + 2); - }, - - easeInCirc: function(t) { - if (t >= 1) { - return t; - } - return -(Math.sqrt(1 - t * t) - 1); - }, - - easeOutCirc: function(t) { - return Math.sqrt(1 - (t = t - 1) * t); - }, - - easeInOutCirc: function(t) { - if ((t /= 0.5) < 1) { - return -0.5 * (Math.sqrt(1 - t * t) - 1); - } - return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, - - easeInElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - }, - - easeOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; - }, - - easeInOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 0.5) === 2) { - return 1; - } - if (!p) { - p = 0.45; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - if (t < 1) { - return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - } - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, - easeInBack: function(t) { - var s = 1.70158; - return t * t * ((s + 1) * t - s); - }, - - easeOutBack: function(t) { - var s = 1.70158; - return (t = t - 1) * t * ((s + 1) * t + s) + 1; - }, - - easeInOutBack: function(t) { - var s = 1.70158; - if ((t /= 0.5) < 1) { - return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - - easeInBounce: function(t) { - return 1 - effects.easeOutBounce(1 - t); - }, - - easeOutBounce: function(t) { - if (t < (1 / 2.75)) { - return 7.5625 * t * t; - } - if (t < (2 / 2.75)) { - return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; - } - if (t < (2.5 / 2.75)) { - return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; - } - return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; - }, - - easeInOutBounce: function(t) { - if (t < 0.5) { - return effects.easeInBounce(t * 2) * 0.5; - } - return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; - } -}; - -module.exports = { - effects: effects -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.easing.effects instead. - * @function Chart.helpers.easingEffects - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.easingEffects = effects; - -},{"43":43}],45:[function(require,module,exports){ -'use strict'; - -var helpers = require(43); - -/** - * @alias Chart.helpers.options - * @namespace - */ -module.exports = { - /** - * Converts the given line height `value` in pixels for a specific font `size`. - * @param {Number|String} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). - * @param {Number} size - The font size (in pixels) used to resolve relative `value`. - * @returns {Number} The effective line height in pixels (size * 1.2 if value is invalid). - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height - * @since 2.7.0 - */ - toLineHeight: function(value, size) { - var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); - if (!matches || matches[1] === 'normal') { - return size * 1.2; - } - - value = +matches[2]; - - switch (matches[3]) { - case 'px': - return value; - case '%': - value /= 100; - break; - default: - break; - } - - return size * value; - }, - - /** - * Converts the given value into a padding object with pre-computed width/height. - * @param {Number|Object} value - If a number, set the value to all TRBL component, - * else, if and object, use defined properties and sets undefined ones to 0. - * @returns {Object} The padding values (top, right, bottom, left, width, height) - * @since 2.7.0 - */ - toPadding: function(value) { - var t, r, b, l; - - if (helpers.isObject(value)) { - t = +value.top || 0; - r = +value.right || 0; - b = +value.bottom || 0; - l = +value.left || 0; - } else { - t = r = b = l = +value || 0; - } - - return { - top: t, - right: r, - bottom: b, - left: l, - height: t + b, - width: l + r - }; - }, - - /** - * Evaluates the given `inputs` sequentially and returns the first defined value. - * @param {Array[]} inputs - An array of values, falling back to the last value. - * @param {Object} [context] - If defined and the current value is a function, the value - * is called with `context` as first argument and the result becomes the new input. - * @param {Number} [index] - If defined and the current value is an array, the value - * at `index` become the new input. - * @since 2.7.0 - */ - resolve: function(inputs, context, index) { - var i, ilen, value; - - for (i = 0, ilen = inputs.length; i < ilen; ++i) { - value = inputs[i]; - if (value === undefined) { - continue; - } - if (context !== undefined && typeof value === 'function') { - value = value(context); - } - if (index !== undefined && helpers.isArray(value)) { - value = value[index]; - } - if (value !== undefined) { - return value; - } - } - } -}; - -},{"43":43}],46:[function(require,module,exports){ -'use strict'; - -module.exports = require(43); -module.exports.easing = require(44); -module.exports.canvas = require(42); -module.exports.options = require(45); - -},{"42":42,"43":43,"44":44,"45":45}],47:[function(require,module,exports){ -/** - * Platform fallback implementation (minimal). - * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 - */ - -module.exports = { - acquireContext: function(item) { - if (item && item.canvas) { - // Support for any object associated to a canvas (including a context2d) - item = item.canvas; - } - - return item && item.getContext('2d') || null; - } -}; - -},{}],48:[function(require,module,exports){ -/** - * Chart.Platform implementation for targeting a web browser - */ - -'use strict'; - -var helpers = require(46); - -var EXPANDO_KEY = '$chartjs'; -var CSS_PREFIX = 'chartjs-'; -var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; -var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; -var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; - -/** - * DOM event types -> Chart.js event types. - * Note: only events with different types are mapped. - * @see https://developer.mozilla.org/en-US/docs/Web/Events - */ -var EVENT_TYPES = { - touchstart: 'mousedown', - touchmove: 'mousemove', - touchend: 'mouseup', - pointerenter: 'mouseenter', - pointerdown: 'mousedown', - pointermove: 'mousemove', - pointerup: 'mouseup', - pointerleave: 'mouseout', - pointerout: 'mouseout' -}; - -/** - * The "used" size is the final value of a dimension property after all calculations have - * been performed. This method uses the computed style of `element` but returns undefined - * if the computed style is not expressed in pixels. That can happen in some cases where - * `element` has a size relative to its parent and this last one is not yet displayed, - * for example because of `display: none` on a parent node. - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value - * @returns {Number} Size in pixels or undefined if unknown. - */ -function readUsedSize(element, property) { - var value = helpers.getStyle(element, property); - var matches = value && value.match(/^(\d+)(\.\d+)?px$/); - return matches ? Number(matches[1]) : undefined; -} - -/** - * Initializes the canvas style and render size without modifying the canvas display size, - * since responsiveness is handled by the controller.resize() method. The config is used - * to determine the aspect ratio to apply in case no explicit height has been specified. - */ -function initCanvas(canvas, config) { - var style = canvas.style; - - // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it - // returns null or '' if no explicit value has been set to the canvas attribute. - var renderHeight = canvas.getAttribute('height'); - var renderWidth = canvas.getAttribute('width'); - - // Chart.js modifies some canvas values that we want to restore on destroy - canvas[EXPANDO_KEY] = { - initial: { - height: renderHeight, - width: renderWidth, - style: { - display: style.display, - height: style.height, - width: style.width - } - } - }; - - // Force canvas to display as block to avoid extra space caused by inline - // elements, which would interfere with the responsive resize process. - // https://github.com/chartjs/Chart.js/issues/2538 - style.display = style.display || 'block'; - - if (renderWidth === null || renderWidth === '') { - var displayWidth = readUsedSize(canvas, 'width'); - if (displayWidth !== undefined) { - canvas.width = displayWidth; - } - } - - if (renderHeight === null || renderHeight === '') { - if (canvas.style.height === '') { - // If no explicit render height and style height, let's apply the aspect ratio, - // which one can be specified by the user but also by charts as default option - // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. - canvas.height = canvas.width / (config.options.aspectRatio || 2); - } else { - var displayHeight = readUsedSize(canvas, 'height'); - if (displayWidth !== undefined) { - canvas.height = displayHeight; - } - } - } - - return canvas; -} - -/** - * Detects support for options object argument in addEventListener. - * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support - * @private - */ -var supportsEventListenerOptions = (function() { - var supports = false; - try { - var options = Object.defineProperty({}, 'passive', { - get: function() { - supports = true; - } - }); - window.addEventListener('e', null, options); - } catch (e) { - // continue regardless of error - } - return supports; -}()); - -// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. -// https://github.com/chartjs/Chart.js/issues/4287 -var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; - -function addEventListener(node, type, listener) { - node.addEventListener(type, listener, eventListenerOptions); -} - -function removeEventListener(node, type, listener) { - node.removeEventListener(type, listener, eventListenerOptions); -} - -function createEvent(type, chart, x, y, nativeEvent) { - return { - type: type, - chart: chart, - native: nativeEvent || null, - x: x !== undefined ? x : null, - y: y !== undefined ? y : null, - }; -} - -function fromNativeEvent(event, chart) { - var type = EVENT_TYPES[event.type] || event.type; - var pos = helpers.getRelativePosition(event, chart); - return createEvent(type, chart, pos.x, pos.y, event); -} - -function throttled(fn, thisArg) { - var ticking = false; - var args = []; - - return function() { - args = Array.prototype.slice.call(arguments); - thisArg = thisArg || this; - - if (!ticking) { - ticking = true; - helpers.requestAnimFrame.call(window, function() { - ticking = false; - fn.apply(thisArg, args); - }); - } - }; -} - -// Implementation based on https://github.com/marcj/css-element-queries -function createResizer(handler) { - var resizer = document.createElement('div'); - var cls = CSS_PREFIX + 'size-monitor'; - var maxSize = 1000000; - var style = - 'position:absolute;' + - 'left:0;' + - 'top:0;' + - 'right:0;' + - 'bottom:0;' + - 'overflow:hidden;' + - 'pointer-events:none;' + - 'visibility:hidden;' + - 'z-index:-1;'; - - resizer.style.cssText = style; - resizer.className = cls; - resizer.innerHTML = - '<div class="' + cls + '-expand" style="' + style + '">' + - '<div style="' + - 'position:absolute;' + - 'width:' + maxSize + 'px;' + - 'height:' + maxSize + 'px;' + - 'left:0;' + - 'top:0">' + - '</div>' + - '</div>' + - '<div class="' + cls + '-shrink" style="' + style + '">' + - '<div style="' + - 'position:absolute;' + - 'width:200%;' + - 'height:200%;' + - 'left:0; ' + - 'top:0">' + - '</div>' + - '</div>'; - - var expand = resizer.childNodes[0]; - var shrink = resizer.childNodes[1]; - - resizer._reset = function() { - expand.scrollLeft = maxSize; - expand.scrollTop = maxSize; - shrink.scrollLeft = maxSize; - shrink.scrollTop = maxSize; - }; - var onScroll = function() { - resizer._reset(); - handler(); - }; - - addEventListener(expand, 'scroll', onScroll.bind(expand, 'expand')); - addEventListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); - - return resizer; -} - -// https://davidwalsh.name/detect-node-insertion -function watchForRender(node, handler) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - var proxy = expando.renderProxy = function(e) { - if (e.animationName === CSS_RENDER_ANIMATION) { - handler(); - } - }; - - helpers.each(ANIMATION_START_EVENTS, function(type) { - addEventListener(node, type, proxy); - }); - - // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class - // is removed then added back immediately (same animation frame?). Accessing the - // `offsetParent` property will force a reflow and re-evaluate the CSS animation. - // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics - // https://github.com/chartjs/Chart.js/issues/4737 - expando.reflow = !!node.offsetParent; - - node.classList.add(CSS_RENDER_MONITOR); -} - -function unwatchForRender(node) { - var expando = node[EXPANDO_KEY] || {}; - var proxy = expando.renderProxy; - - if (proxy) { - helpers.each(ANIMATION_START_EVENTS, function(type) { - removeEventListener(node, type, proxy); - }); - - delete expando.renderProxy; - } - - node.classList.remove(CSS_RENDER_MONITOR); -} - -function addResizeListener(node, listener, chart) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - - // Let's keep track of this added resizer and thus avoid DOM query when removing it. - var resizer = expando.resizer = createResizer(throttled(function() { - if (expando.resizer) { - return listener(createEvent('resize', chart)); - } - })); - - // The resizer needs to be attached to the node parent, so we first need to be - // sure that `node` is attached to the DOM before injecting the resizer element. - watchForRender(node, function() { - if (expando.resizer) { - var container = node.parentNode; - if (container && container !== resizer.parentNode) { - container.insertBefore(resizer, container.firstChild); - } - - // The container size might have changed, let's reset the resizer state. - resizer._reset(); - } - }); -} - -function removeResizeListener(node) { - var expando = node[EXPANDO_KEY] || {}; - var resizer = expando.resizer; - - delete expando.resizer; - unwatchForRender(node); - - if (resizer && resizer.parentNode) { - resizer.parentNode.removeChild(resizer); - } -} - -function injectCSS(platform, css) { - // http://stackoverflow.com/q/3922139 - var style = platform._style || document.createElement('style'); - if (!platform._style) { - platform._style = style; - css = '/* Chart.js */\n' + css; - style.setAttribute('type', 'text/css'); - document.getElementsByTagName('head')[0].appendChild(style); - } - - style.appendChild(document.createTextNode(css)); -} - -module.exports = { - /** - * This property holds whether this platform is enabled for the current environment. - * Currently used by platform.js to select the proper implementation. - * @private - */ - _enabled: typeof window !== 'undefined' && typeof document !== 'undefined', - - initialize: function() { - var keyframes = 'from{opacity:0.99}to{opacity:1}'; - - injectCSS(this, - // DOM rendering detection - // https://davidwalsh.name/detect-node-insertion - '@-webkit-keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' + - '@keyframes ' + CSS_RENDER_ANIMATION + '{' + keyframes + '}' + - '.' + CSS_RENDER_MONITOR + '{' + - '-webkit-animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' + - 'animation:' + CSS_RENDER_ANIMATION + ' 0.001s;' + - '}' - ); - }, - - acquireContext: function(item, config) { - if (typeof item === 'string') { - item = document.getElementById(item); - } else if (item.length) { - // Support for array based queries (such as jQuery) - item = item[0]; - } - - if (item && item.canvas) { - // Support for any object associated to a canvas (including a context2d) - item = item.canvas; - } - - // To prevent canvas fingerprinting, some add-ons undefine the getContext - // method, for example: https://github.com/kkapsner/CanvasBlocker - // https://github.com/chartjs/Chart.js/issues/2807 - var context = item && item.getContext && item.getContext('2d'); - - // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is - // inside an iframe or when running in a protected environment. We could guess the - // types from their toString() value but let's keep things flexible and assume it's - // a sufficient condition if the item has a context2D which has item as `canvas`. - // https://github.com/chartjs/Chart.js/issues/3887 - // https://github.com/chartjs/Chart.js/issues/4102 - // https://github.com/chartjs/Chart.js/issues/4152 - if (context && context.canvas === item) { - initCanvas(item, config); - return context; - } - - return null; - }, - - releaseContext: function(context) { - var canvas = context.canvas; - if (!canvas[EXPANDO_KEY]) { - return; - } - - var initial = canvas[EXPANDO_KEY].initial; - ['height', 'width'].forEach(function(prop) { - var value = initial[prop]; - if (helpers.isNullOrUndef(value)) { - canvas.removeAttribute(prop); - } else { - canvas.setAttribute(prop, value); - } - }); - - helpers.each(initial.style || {}, function(value, key) { - canvas.style[key] = value; - }); - - // The canvas render size might have been changed (and thus the state stack discarded), - // we can't use save() and restore() to restore the initial state. So make sure that at - // least the canvas context is reset to the default state by setting the canvas width. - // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html - canvas.width = canvas.width; - - delete canvas[EXPANDO_KEY]; - }, - - addEventListener: function(chart, type, listener) { - var canvas = chart.canvas; - if (type === 'resize') { - // Note: the resize event is not supported on all browsers. - addResizeListener(canvas, listener, chart); - return; - } - - var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {}); - var proxies = expando.proxies || (expando.proxies = {}); - var proxy = proxies[chart.id + '_' + type] = function(event) { - listener(fromNativeEvent(event, chart)); - }; - - addEventListener(canvas, type, proxy); - }, - - removeEventListener: function(chart, type, listener) { - var canvas = chart.canvas; - if (type === 'resize') { - // Note: the resize event is not supported on all browsers. - removeResizeListener(canvas, listener); - return; - } - - var expando = listener[EXPANDO_KEY] || {}; - var proxies = expando.proxies || {}; - var proxy = proxies[chart.id + '_' + type]; - if (!proxy) { - return; - } - - removeEventListener(canvas, type, proxy); - } -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use EventTarget.addEventListener instead. - * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ - * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener - * @function Chart.helpers.addEvent - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.addEvent = addEventListener; - -/** - * Provided for backward compatibility, use EventTarget.removeEventListener instead. - * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ - * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener - * @function Chart.helpers.removeEvent - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.removeEvent = removeEventListener; - -},{"46":46}],49:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); -var basic = require(47); -var dom = require(48); - -// @TODO Make possible to select another platform at build time. -var implementation = dom._enabled ? dom : basic; - -/** - * @namespace Chart.platform - * @see https://chartjs.gitbooks.io/proposals/content/Platform.html - * @since 2.4.0 - */ -module.exports = helpers.extend({ - /** - * @since 2.7.0 - */ - initialize: function() {}, - - /** - * Called at chart construction time, returns a context2d instance implementing - * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}. - * @param {*} item - The native item from which to acquire context (platform specific) - * @param {Object} options - The chart options - * @returns {CanvasRenderingContext2D} context2d instance - */ - acquireContext: function() {}, - - /** - * Called at chart destruction time, releases any resources associated to the context - * previously returned by the acquireContext() method. - * @param {CanvasRenderingContext2D} context - The context2d instance - * @returns {Boolean} true if the method succeeded, else false - */ - releaseContext: function() {}, - - /** - * Registers the specified listener on the given chart. - * @param {Chart} chart - Chart from which to listen for event - * @param {String} type - The ({@link IEvent}) type to listen for - * @param {Function} listener - Receives a notification (an object that implements - * the {@link IEvent} interface) when an event of the specified type occurs. - */ - addEventListener: function() {}, - - /** - * Removes the specified listener previously registered with addEventListener. - * @param {Chart} chart -Chart from which to remove the listener - * @param {String} type - The ({@link IEvent}) type to remove - * @param {Function} listener - The listener function to remove from the event target. - */ - removeEventListener: function() {} - -}, implementation); - -/** - * @interface IPlatform - * Allows abstracting platform dependencies away from the chart - * @borrows Chart.platform.acquireContext as acquireContext - * @borrows Chart.platform.releaseContext as releaseContext - * @borrows Chart.platform.addEventListener as addEventListener - * @borrows Chart.platform.removeEventListener as removeEventListener - */ - -/** - * @interface IEvent - * @prop {String} type - The event type name, possible values are: - * 'contextmenu', 'mouseenter', 'mousedown', 'mousemove', 'mouseup', 'mouseout', - * 'click', 'dblclick', 'keydown', 'keypress', 'keyup' and 'resize' - * @prop {*} native - The original native event (null for emulated events, e.g. 'resize') - * @prop {Number} x - The mouse x position, relative to the canvas (null for incompatible events) - * @prop {Number} y - The mouse y position, relative to the canvas (null for incompatible events) - */ - -},{"46":46,"47":47,"48":48}],50:[function(require,module,exports){ -'use strict'; - -module.exports = {}; -module.exports.filler = require(51); -module.exports.legend = require(52); -module.exports.title = require(53); - -},{"51":51,"52":52,"53":53}],51:[function(require,module,exports){ -/** - * Plugin based on discussion from the following Chart.js issues: - * @see https://github.com/chartjs/Chart.js/issues/2380#issuecomment-279961569 - * @see https://github.com/chartjs/Chart.js/issues/2440#issuecomment-256461897 - */ - -'use strict'; - -var defaults = require(26); -var elements = require(41); -var helpers = require(46); - -defaults._set('global', { - plugins: { - filler: { - propagate: true - } - } -}); - -var mappers = { - dataset: function(source) { - var index = source.fill; - var chart = source.chart; - var meta = chart.getDatasetMeta(index); - var visible = meta && chart.isDatasetVisible(index); - var points = (visible && meta.dataset._children) || []; - var length = points.length || 0; - - return !length ? null : function(point, i) { - return (i < length && points[i]._view) || null; - }; - }, - - boundary: function(source) { - var boundary = source.boundary; - var x = boundary ? boundary.x : null; - var y = boundary ? boundary.y : null; - - return function(point) { - return { - x: x === null ? point.x : x, - y: y === null ? point.y : y, - }; - }; - } -}; - -// @todo if (fill[0] === '#') -function decodeFill(el, index, count) { - var model = el._model || {}; - var fill = model.fill; - var target; - - if (fill === undefined) { - fill = !!model.backgroundColor; - } - - if (fill === false || fill === null) { - return false; - } - - if (fill === true) { - return 'origin'; - } - - target = parseFloat(fill, 10); - if (isFinite(target) && Math.floor(target) === target) { - if (fill[0] === '-' || fill[0] === '+') { - target = index + target; - } - - if (target === index || target < 0 || target >= count) { - return false; - } - - return target; - } - - switch (fill) { - // compatibility - case 'bottom': - return 'start'; - case 'top': - return 'end'; - case 'zero': - return 'origin'; - // supported boundaries - case 'origin': - case 'start': - case 'end': - return fill; - // invalid fill values - default: - return false; - } -} - -function computeBoundary(source) { - var model = source.el._model || {}; - var scale = source.el._scale || {}; - var fill = source.fill; - var target = null; - var horizontal; - - if (isFinite(fill)) { - return null; - } - - // Backward compatibility: until v3, we still need to support boundary values set on - // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and - // controllers might still use it (e.g. the Smith chart). - - if (fill === 'start') { - target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom; - } else if (fill === 'end') { - target = model.scaleTop === undefined ? scale.top : model.scaleTop; - } else if (model.scaleZero !== undefined) { - target = model.scaleZero; - } else if (scale.getBasePosition) { - target = scale.getBasePosition(); - } else if (scale.getBasePixel) { - target = scale.getBasePixel(); - } - - if (target !== undefined && target !== null) { - if (target.x !== undefined && target.y !== undefined) { - return target; - } - - if (typeof target === 'number' && isFinite(target)) { - horizontal = scale.isHorizontal(); - return { - x: horizontal ? target : null, - y: horizontal ? null : target - }; - } - } - - return null; -} - -function resolveTarget(sources, index, propagate) { - var source = sources[index]; - var fill = source.fill; - var visited = [index]; - var target; - - if (!propagate) { - return fill; - } - - while (fill !== false && visited.indexOf(fill) === -1) { - if (!isFinite(fill)) { - return fill; - } - - target = sources[fill]; - if (!target) { - return false; - } - - if (target.visible) { - return fill; - } - - visited.push(fill); - fill = target.fill; - } - - return false; -} - -function createMapper(source) { - var fill = source.fill; - var type = 'dataset'; - - if (fill === false) { - return null; - } - - if (!isFinite(fill)) { - type = 'boundary'; - } - - return mappers[type](source); -} - -function isDrawable(point) { - return point && !point.skip; -} - -function drawArea(ctx, curve0, curve1, len0, len1) { - var i; - - if (!len0 || !len1) { - return; - } - - // building first area curve (normal) - ctx.moveTo(curve0[0].x, curve0[0].y); - for (i = 1; i < len0; ++i) { - helpers.canvas.lineTo(ctx, curve0[i - 1], curve0[i]); - } - - // joining the two area curves - ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y); - - // building opposite area curve (reverse) - for (i = len1 - 1; i > 0; --i) { - helpers.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true); - } -} - -function doFill(ctx, points, mapper, view, color, loop) { - var count = points.length; - var span = view.spanGaps; - var curve0 = []; - var curve1 = []; - var len0 = 0; - var len1 = 0; - var i, ilen, index, p0, p1, d0, d1; - - ctx.beginPath(); - - for (i = 0, ilen = (count + !!loop); i < ilen; ++i) { - index = i % count; - p0 = points[index]._view; - p1 = mapper(p0, index, view); - d0 = isDrawable(p0); - d1 = isDrawable(p1); - - if (d0 && d1) { - len0 = curve0.push(p0); - len1 = curve1.push(p1); - } else if (len0 && len1) { - if (!span) { - drawArea(ctx, curve0, curve1, len0, len1); - len0 = len1 = 0; - curve0 = []; - curve1 = []; - } else { - if (d0) { - curve0.push(p0); - } - if (d1) { - curve1.push(p1); - } - } - } - } - - drawArea(ctx, curve0, curve1, len0, len1); - - ctx.closePath(); - ctx.fillStyle = color; - ctx.fill(); -} - -module.exports = { - id: 'filler', - - afterDatasetsUpdate: function(chart, options) { - var count = (chart.data.datasets || []).length; - var propagate = options.propagate; - var sources = []; - var meta, i, el, source; - - for (i = 0; i < count; ++i) { - meta = chart.getDatasetMeta(i); - el = meta.dataset; - source = null; - - if (el && el._model && el instanceof elements.Line) { - source = { - visible: chart.isDatasetVisible(i), - fill: decodeFill(el, i, count), - chart: chart, - el: el - }; - } - - meta.$filler = source; - sources.push(source); - } - - for (i = 0; i < count; ++i) { - source = sources[i]; - if (!source) { - continue; - } - - source.fill = resolveTarget(sources, i, propagate); - source.boundary = computeBoundary(source); - source.mapper = createMapper(source); - } - }, - - beforeDatasetDraw: function(chart, args) { - var meta = args.meta.$filler; - if (!meta) { - return; - } - - var ctx = chart.ctx; - var el = meta.el; - var view = el._view; - var points = el._children || []; - var mapper = meta.mapper; - var color = view.backgroundColor || defaults.global.defaultColor; - - if (mapper && color && points.length) { - helpers.canvas.clipArea(ctx, chart.chartArea); - doFill(ctx, points, mapper, view, color, el._loop); - helpers.canvas.unclipArea(ctx); - } - } -}; - -},{"26":26,"41":41,"46":46}],52:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); -var layouts = require(31); - -var noop = helpers.noop; - -defaults._set('global', { - legend: { - display: true, - position: 'top', - fullWidth: true, - reverse: false, - weight: 1000, - - // a callback that will handle - onClick: function(e, legendItem) { - var index = legendItem.datasetIndex; - var ci = this.chart; - var meta = ci.getDatasetMeta(index); - - // See controller.isDatasetVisible comment - meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null; - - // We hid a dataset ... rerender the chart - ci.update(); - }, - - onHover: null, - - labels: { - boxWidth: 40, - padding: 10, - // Generates labels shown in the legend - // Valid properties to return: - // text : text to display - // fillStyle : fill of coloured box - // strokeStyle: stroke of coloured box - // hidden : if this legend item refers to a hidden item - // lineCap : cap style for line - // lineDash - // lineDashOffset : - // lineJoin : - // lineWidth : - generateLabels: function(chart) { - var data = chart.data; - return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) { - return { - text: dataset.label, - fillStyle: (!helpers.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]), - hidden: !chart.isDatasetVisible(i), - lineCap: dataset.borderCapStyle, - lineDash: dataset.borderDash, - lineDashOffset: dataset.borderDashOffset, - lineJoin: dataset.borderJoinStyle, - lineWidth: dataset.borderWidth, - strokeStyle: dataset.borderColor, - pointStyle: dataset.pointStyle, - - // Below is extra data used for toggling the datasets - datasetIndex: i - }; - }, this) : []; - } - } - }, - - legendCallback: function(chart) { - var text = []; - text.push('<ul class="' + chart.id + '-legend">'); - for (var i = 0; i < chart.data.datasets.length; i++) { - text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '"></span>'); - if (chart.data.datasets[i].label) { - text.push(chart.data.datasets[i].label); - } - text.push('</li>'); - } - text.push('</ul>'); - return text.join(''); - } -}); - -/** - * Helper function to get the box width based on the usePointStyle option - * @param labelopts {Object} the label options on the legend - * @param fontSize {Number} the label font size - * @return {Number} width of the color box area - */ -function getBoxWidth(labelOpts, fontSize) { - return labelOpts.usePointStyle ? - fontSize * Math.SQRT2 : - labelOpts.boxWidth; -} - -/** - * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! - */ -var Legend = Element.extend({ - - initialize: function(config) { - helpers.extend(this, config); - - // Contains hit boxes for each dataset (in dataset order) - this.legendHitBoxes = []; - - // Are we in doughnut mode which has a different data type - this.doughnutMode = false; - }, - - // These methods are ordered by lifecycle. Utilities then follow. - // Any function defined here is inherited by all legend types. - // Any function can be extended by the legend type - - beforeUpdate: noop, - update: function(maxWidth, maxHeight, margins) { - var me = this; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = margins; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - // Labels - me.beforeBuildLabels(); - me.buildLabels(); - me.afterBuildLabels(); - - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - }, - afterUpdate: noop, - - // - - beforeSetDimensions: noop, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - - // Reset minSize - me.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: noop, - - // - - beforeBuildLabels: noop, - buildLabels: function() { - var me = this; - var labelOpts = me.options.labels || {}; - var legendItems = helpers.callback(labelOpts.generateLabels, [me.chart], me) || []; - - if (labelOpts.filter) { - legendItems = legendItems.filter(function(item) { - return labelOpts.filter(item, me.chart.data); - }); - } - - if (me.options.reverse) { - legendItems.reverse(); - } - - me.legendItems = legendItems; - }, - afterBuildLabels: noop, - - // - - beforeFit: noop, - fit: function() { - var me = this; - var opts = me.options; - var labelOpts = opts.labels; - var display = opts.display; - - var ctx = me.ctx; - - var globalDefault = defaults.global; - var valueOrDefault = helpers.valueOrDefault; - var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize); - var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle); - var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily); - var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); - - // Reset hit boxes - var hitboxes = me.legendHitBoxes = []; - - var minSize = me.minSize; - var isHorizontal = me.isHorizontal(); - - if (isHorizontal) { - minSize.width = me.maxWidth; // fill all the width - minSize.height = display ? 10 : 0; - } else { - minSize.width = display ? 10 : 0; - minSize.height = me.maxHeight; // fill all the height - } - - // Increase sizes here - if (display) { - ctx.font = labelFont; - - if (isHorizontal) { - // Labels - - // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one - var lineWidths = me.lineWidths = [0]; - var totalHeight = me.legendItems.length ? fontSize + (labelOpts.padding) : 0; - - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - - helpers.each(me.legendItems, function(legendItem, i) { - var boxWidth = getBoxWidth(labelOpts, fontSize); - var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; - - if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) { - totalHeight += fontSize + (labelOpts.padding); - lineWidths[lineWidths.length] = me.left; - } - - // Store the hitbox width and height here. Final position will be updated in `draw` - hitboxes[i] = { - left: 0, - top: 0, - width: width, - height: fontSize - }; - - lineWidths[lineWidths.length - 1] += width + labelOpts.padding; - }); - - minSize.height += totalHeight; - - } else { - var vPadding = labelOpts.padding; - var columnWidths = me.columnWidths = []; - var totalWidth = labelOpts.padding; - var currentColWidth = 0; - var currentColHeight = 0; - var itemHeight = fontSize + vPadding; - - helpers.each(me.legendItems, function(legendItem, i) { - var boxWidth = getBoxWidth(labelOpts, fontSize); - var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; - - // If too tall, go to new column - if (currentColHeight + itemHeight > minSize.height) { - totalWidth += currentColWidth + labelOpts.padding; - columnWidths.push(currentColWidth); // previous column width - - currentColWidth = 0; - currentColHeight = 0; - } - - // Get max width - currentColWidth = Math.max(currentColWidth, itemWidth); - currentColHeight += itemHeight; - - // Store the hitbox width and height here. Final position will be updated in `draw` - hitboxes[i] = { - left: 0, - top: 0, - width: itemWidth, - height: fontSize - }; - }); - - totalWidth += currentColWidth; - columnWidths.push(currentColWidth); - minSize.width += totalWidth; - } - } - - me.width = minSize.width; - me.height = minSize.height; - }, - afterFit: noop, - - // Shared Methods - isHorizontal: function() { - return this.options.position === 'top' || this.options.position === 'bottom'; - }, - - // Actually draw the legend on the canvas - draw: function() { - var me = this; - var opts = me.options; - var labelOpts = opts.labels; - var globalDefault = defaults.global; - var lineDefault = globalDefault.elements.line; - var legendWidth = me.width; - var lineWidths = me.lineWidths; - - if (opts.display) { - var ctx = me.ctx; - var valueOrDefault = helpers.valueOrDefault; - var fontColor = valueOrDefault(labelOpts.fontColor, globalDefault.defaultFontColor); - var fontSize = valueOrDefault(labelOpts.fontSize, globalDefault.defaultFontSize); - var fontStyle = valueOrDefault(labelOpts.fontStyle, globalDefault.defaultFontStyle); - var fontFamily = valueOrDefault(labelOpts.fontFamily, globalDefault.defaultFontFamily); - var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily); - var cursor; - - // Canvas setup - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - ctx.lineWidth = 0.5; - ctx.strokeStyle = fontColor; // for strikethrough effect - ctx.fillStyle = fontColor; // render in correct colour - ctx.font = labelFont; - - var boxWidth = getBoxWidth(labelOpts, fontSize); - var hitboxes = me.legendHitBoxes; - - // current position - var drawLegendBox = function(x, y, legendItem) { - if (isNaN(boxWidth) || boxWidth <= 0) { - return; - } - - // Set the ctx for the box - ctx.save(); - - ctx.fillStyle = valueOrDefault(legendItem.fillStyle, globalDefault.defaultColor); - ctx.lineCap = valueOrDefault(legendItem.lineCap, lineDefault.borderCapStyle); - ctx.lineDashOffset = valueOrDefault(legendItem.lineDashOffset, lineDefault.borderDashOffset); - ctx.lineJoin = valueOrDefault(legendItem.lineJoin, lineDefault.borderJoinStyle); - ctx.lineWidth = valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth); - ctx.strokeStyle = valueOrDefault(legendItem.strokeStyle, globalDefault.defaultColor); - var isLineWidthZero = (valueOrDefault(legendItem.lineWidth, lineDefault.borderWidth) === 0); - - if (ctx.setLineDash) { - // IE 9 and 10 do not support line dash - ctx.setLineDash(valueOrDefault(legendItem.lineDash, lineDefault.borderDash)); - } - - if (opts.labels && opts.labels.usePointStyle) { - // Recalculate x and y for drawPoint() because its expecting - // x and y to be center of figure (instead of top left) - var radius = fontSize * Math.SQRT2 / 2; - var offSet = radius / Math.SQRT2; - var centerX = x + offSet; - var centerY = y + offSet; - - // Draw pointStyle as legend symbol - helpers.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY); - } else { - // Draw box as legend symbol - if (!isLineWidthZero) { - ctx.strokeRect(x, y, boxWidth, fontSize); - } - ctx.fillRect(x, y, boxWidth, fontSize); - } - - ctx.restore(); - }; - var fillText = function(x, y, legendItem, textWidth) { - var halfFontSize = fontSize / 2; - var xLeft = boxWidth + halfFontSize + x; - var yMiddle = y + halfFontSize; - - ctx.fillText(legendItem.text, xLeft, yMiddle); - - if (legendItem.hidden) { - // Strikethrough the text if hidden - ctx.beginPath(); - ctx.lineWidth = 2; - ctx.moveTo(xLeft, yMiddle); - ctx.lineTo(xLeft + textWidth, yMiddle); - ctx.stroke(); - } - }; - - // Horizontal - var isHorizontal = me.isHorizontal(); - if (isHorizontal) { - cursor = { - x: me.left + ((legendWidth - lineWidths[0]) / 2), - y: me.top + labelOpts.padding, - line: 0 - }; - } else { - cursor = { - x: me.left + labelOpts.padding, - y: me.top + labelOpts.padding, - line: 0 - }; - } - - var itemHeight = fontSize + labelOpts.padding; - helpers.each(me.legendItems, function(legendItem, i) { - var textWidth = ctx.measureText(legendItem.text).width; - var width = boxWidth + (fontSize / 2) + textWidth; - var x = cursor.x; - var y = cursor.y; - - if (isHorizontal) { - if (x + width >= legendWidth) { - y = cursor.y += itemHeight; - cursor.line++; - x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2); - } - } else if (y + itemHeight > me.bottom) { - x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding; - y = cursor.y = me.top + labelOpts.padding; - cursor.line++; - } - - drawLegendBox(x, y, legendItem); - - hitboxes[i].left = x; - hitboxes[i].top = y; - - // Fill the actual label - fillText(x, y, legendItem, textWidth); - - if (isHorizontal) { - cursor.x += width + (labelOpts.padding); - } else { - cursor.y += itemHeight; - } - - }); - } - }, - - /** - * Handle an event - * @private - * @param {IEvent} event - The event to handle - * @return {Boolean} true if a change occured - */ - handleEvent: function(e) { - var me = this; - var opts = me.options; - var type = e.type === 'mouseup' ? 'click' : e.type; - var changed = false; - - if (type === 'mousemove') { - if (!opts.onHover) { - return; - } - } else if (type === 'click') { - if (!opts.onClick) { - return; - } - } else { - return; - } - - // Chart event already has relative position in it - var x = e.x; - var y = e.y; - - if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) { - // See if we are touching one of the dataset boxes - var lh = me.legendHitBoxes; - for (var i = 0; i < lh.length; ++i) { - var hitBox = lh[i]; - - if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) { - // Touching an element - if (type === 'click') { - // use e.native for backwards compatibility - opts.onClick.call(me, e.native, me.legendItems[i]); - changed = true; - break; - } else if (type === 'mousemove') { - // use e.native for backwards compatibility - opts.onHover.call(me, e.native, me.legendItems[i]); - changed = true; - break; - } - } - } - } - - return changed; - } -}); - -function createNewLegendAndAttach(chart, legendOpts) { - var legend = new Legend({ - ctx: chart.ctx, - options: legendOpts, - chart: chart - }); - - layouts.configure(chart, legend, legendOpts); - layouts.addBox(chart, legend); - chart.legend = legend; -} - -module.exports = { - id: 'legend', - - /** - * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making - * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of - * the plugin, which one will be re-exposed in the chart.js file. - * https://github.com/chartjs/Chart.js/pull/2640 - * @private - */ - _element: Legend, - - beforeInit: function(chart) { - var legendOpts = chart.options.legend; - - if (legendOpts) { - createNewLegendAndAttach(chart, legendOpts); - } - }, - - beforeUpdate: function(chart) { - var legendOpts = chart.options.legend; - var legend = chart.legend; - - if (legendOpts) { - helpers.mergeIf(legendOpts, defaults.global.legend); - - if (legend) { - layouts.configure(chart, legend, legendOpts); - legend.options = legendOpts; - } else { - createNewLegendAndAttach(chart, legendOpts); - } - } else if (legend) { - layouts.removeBox(chart, legend); - delete chart.legend; - } - }, - - afterEvent: function(chart, e) { - var legend = chart.legend; - if (legend) { - legend.handleEvent(e); - } - } -}; - -},{"26":26,"27":27,"31":31,"46":46}],53:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var Element = require(27); -var helpers = require(46); -var layouts = require(31); - -var noop = helpers.noop; - -defaults._set('global', { - title: { - display: false, - fontStyle: 'bold', - fullWidth: true, - lineHeight: 1.2, - padding: 10, - position: 'top', - text: '', - weight: 2000 // by default greater than legend (1000) to be above - } -}); - -/** - * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! - */ -var Title = Element.extend({ - initialize: function(config) { - var me = this; - helpers.extend(me, config); - - // Contains hit boxes for each dataset (in dataset order) - me.legendHitBoxes = []; - }, - - // These methods are ordered by lifecycle. Utilities then follow. - - beforeUpdate: noop, - update: function(maxWidth, maxHeight, margins) { - var me = this; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = margins; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - // Labels - me.beforeBuildLabels(); - me.buildLabels(); - me.afterBuildLabels(); - - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - - }, - afterUpdate: noop, - - // - - beforeSetDimensions: noop, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - - // Reset minSize - me.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: noop, - - // - - beforeBuildLabels: noop, - buildLabels: noop, - afterBuildLabels: noop, - - // - - beforeFit: noop, - fit: function() { - var me = this; - var valueOrDefault = helpers.valueOrDefault; - var opts = me.options; - var display = opts.display; - var fontSize = valueOrDefault(opts.fontSize, defaults.global.defaultFontSize); - var minSize = me.minSize; - var lineCount = helpers.isArray(opts.text) ? opts.text.length : 1; - var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize); - var textSize = display ? (lineCount * lineHeight) + (opts.padding * 2) : 0; - - if (me.isHorizontal()) { - minSize.width = me.maxWidth; // fill all the width - minSize.height = textSize; - } else { - minSize.width = textSize; - minSize.height = me.maxHeight; // fill all the height - } - - me.width = minSize.width; - me.height = minSize.height; - - }, - afterFit: noop, - - // Shared Methods - isHorizontal: function() { - var pos = this.options.position; - return pos === 'top' || pos === 'bottom'; - }, - - // Actually draw the title block on the canvas - draw: function() { - var me = this; - var ctx = me.ctx; - var valueOrDefault = helpers.valueOrDefault; - var opts = me.options; - var globalDefaults = defaults.global; - - if (opts.display) { - var fontSize = valueOrDefault(opts.fontSize, globalDefaults.defaultFontSize); - var fontStyle = valueOrDefault(opts.fontStyle, globalDefaults.defaultFontStyle); - var fontFamily = valueOrDefault(opts.fontFamily, globalDefaults.defaultFontFamily); - var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily); - var lineHeight = helpers.options.toLineHeight(opts.lineHeight, fontSize); - var offset = lineHeight / 2 + opts.padding; - var rotation = 0; - var top = me.top; - var left = me.left; - var bottom = me.bottom; - var right = me.right; - var maxWidth, titleX, titleY; - - ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour - ctx.font = titleFont; - - // Horizontal - if (me.isHorizontal()) { - titleX = left + ((right - left) / 2); // midpoint of the width - titleY = top + offset; - maxWidth = right - left; - } else { - titleX = opts.position === 'left' ? left + offset : right - offset; - titleY = top + ((bottom - top) / 2); - maxWidth = bottom - top; - rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5); - } - - ctx.save(); - ctx.translate(titleX, titleY); - ctx.rotate(rotation); - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - - var text = opts.text; - if (helpers.isArray(text)) { - var y = 0; - for (var i = 0; i < text.length; ++i) { - ctx.fillText(text[i], 0, y, maxWidth); - y += lineHeight; - } - } else { - ctx.fillText(text, 0, 0, maxWidth); - } - - ctx.restore(); - } - } -}); - -function createNewTitleBlockAndAttach(chart, titleOpts) { - var title = new Title({ - ctx: chart.ctx, - options: titleOpts, - chart: chart - }); - - layouts.configure(chart, title, titleOpts); - layouts.addBox(chart, title); - chart.titleBlock = title; -} - -module.exports = { - id: 'title', - - /** - * Backward compatibility: since 2.1.5, the title is registered as a plugin, making - * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of - * the plugin, which one will be re-exposed in the chart.js file. - * https://github.com/chartjs/Chart.js/pull/2640 - * @private - */ - _element: Title, - - beforeInit: function(chart) { - var titleOpts = chart.options.title; - - if (titleOpts) { - createNewTitleBlockAndAttach(chart, titleOpts); - } - }, - - beforeUpdate: function(chart) { - var titleOpts = chart.options.title; - var titleBlock = chart.titleBlock; - - if (titleOpts) { - helpers.mergeIf(titleOpts, defaults.global.title); - - if (titleBlock) { - layouts.configure(chart, titleBlock, titleOpts); - titleBlock.options = titleOpts; - } else { - createNewTitleBlockAndAttach(chart, titleOpts); - } - } else if (titleBlock) { - layouts.removeBox(chart, titleBlock); - delete chart.titleBlock; - } - } -}; - -},{"26":26,"27":27,"31":31,"46":46}],54:[function(require,module,exports){ -'use strict'; - -var Scale = require(33); -var scaleService = require(34); - -module.exports = function() { - - // Default config for a category scale - var defaultConfig = { - position: 'bottom' - }; - - var DatasetScale = Scale.extend({ - /** - * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those - * else fall back to data.labels - * @private - */ - getLabels: function() { - var data = this.chart.data; - return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels; - }, - - determineDataLimits: function() { - var me = this; - var labels = me.getLabels(); - me.minIndex = 0; - me.maxIndex = labels.length - 1; - var findIndex; - - if (me.options.ticks.min !== undefined) { - // user specified min value - findIndex = labels.indexOf(me.options.ticks.min); - me.minIndex = findIndex !== -1 ? findIndex : me.minIndex; - } - - if (me.options.ticks.max !== undefined) { - // user specified max value - findIndex = labels.indexOf(me.options.ticks.max); - me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex; - } - - me.min = labels[me.minIndex]; - me.max = labels[me.maxIndex]; - }, - - buildTicks: function() { - var me = this; - var labels = me.getLabels(); - // If we are viewing some subset of labels, slice the original array - me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1); - }, - - getLabelForIndex: function(index, datasetIndex) { - var me = this; - var data = me.chart.data; - var isHorizontal = me.isHorizontal(); - - if (data.yLabels && !isHorizontal) { - return me.getRightValue(data.datasets[datasetIndex].data[index]); - } - return me.ticks[index - me.minIndex]; - }, - - // Used to get data value locations. Value can either be an index or a numerical value - getPixelForValue: function(value, index) { - var me = this; - var offset = me.options.offset; - // 1 is added because we need the length but we have the indexes - var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1); - - // If value is a data object, then index is the index in the data array, - // not the index of the scale. We need to change that. - var valueCategory; - if (value !== undefined && value !== null) { - valueCategory = me.isHorizontal() ? value.x : value.y; - } - if (valueCategory !== undefined || (value !== undefined && isNaN(index))) { - var labels = me.getLabels(); - value = valueCategory || value; - var idx = labels.indexOf(value); - index = idx !== -1 ? idx : index; - } - - if (me.isHorizontal()) { - var valueWidth = me.width / offsetAmt; - var widthOffset = (valueWidth * (index - me.minIndex)); - - if (offset) { - widthOffset += (valueWidth / 2); - } - - return me.left + Math.round(widthOffset); - } - var valueHeight = me.height / offsetAmt; - var heightOffset = (valueHeight * (index - me.minIndex)); - - if (offset) { - heightOffset += (valueHeight / 2); - } - - return me.top + Math.round(heightOffset); - }, - getPixelForTick: function(index) { - return this.getPixelForValue(this.ticks[index], index + this.minIndex, null); - }, - getValueForPixel: function(pixel) { - var me = this; - var offset = me.options.offset; - var value; - var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1); - var horz = me.isHorizontal(); - var valueDimension = (horz ? me.width : me.height) / offsetAmt; - - pixel -= horz ? me.left : me.top; - - if (offset) { - pixel -= (valueDimension / 2); - } - - if (pixel <= 0) { - value = 0; - } else { - value = Math.round(pixel / valueDimension); - } - - return value + me.minIndex; - }, - getBasePixel: function() { - return this.bottom; - } - }); - - scaleService.registerScaleType('category', DatasetScale, defaultConfig); -}; - -},{"33":33,"34":34}],55:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var helpers = require(46); -var scaleService = require(34); -var Ticks = require(35); - -module.exports = function(Chart) { - - var defaultConfig = { - position: 'left', - ticks: { - callback: Ticks.formatters.linear - } - }; - - var LinearScale = Chart.LinearScaleBase.extend({ - - determineDataLimits: function() { - var me = this; - var opts = me.options; - var chart = me.chart; - var data = chart.data; - var datasets = data.datasets; - var isHorizontal = me.isHorizontal(); - var DEFAULT_MIN = 0; - var DEFAULT_MAX = 1; - - function IDMatches(meta) { - return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; - } - - // First Calculate the range - me.min = null; - me.max = null; - - var hasStacks = opts.stacked; - if (hasStacks === undefined) { - helpers.each(datasets, function(dataset, datasetIndex) { - if (hasStacks) { - return; - } - - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && - meta.stack !== undefined) { - hasStacks = true; - } - }); - } - - if (opts.stacked || hasStacks) { - var valuesPerStack = {}; - - helpers.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - var key = [ - meta.type, - // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined - ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), - meta.stack - ].join('.'); - - if (valuesPerStack[key] === undefined) { - valuesPerStack[key] = { - positiveValues: [], - negativeValues: [] - }; - } - - // Store these per type - var positiveValues = valuesPerStack[key].positiveValues; - var negativeValues = valuesPerStack[key].negativeValues; - - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - positiveValues[index] = positiveValues[index] || 0; - negativeValues[index] = negativeValues[index] || 0; - - if (opts.relativePoints) { - positiveValues[index] = 100; - } else if (value < 0) { - negativeValues[index] += value; - } else { - positiveValues[index] += value; - } - }); - } - }); - - helpers.each(valuesPerStack, function(valuesForType) { - var values = valuesForType.positiveValues.concat(valuesForType.negativeValues); - var minVal = helpers.min(values); - var maxVal = helpers.max(values); - me.min = me.min === null ? minVal : Math.min(me.min, minVal); - me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); - }); - - } else { - helpers.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; - } - - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; - } - }); - } - }); - } - - me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN; - me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX; - - // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero - this.handleTickRangeOptions(); - }, - getTickLimit: function() { - var maxTicks; - var me = this; - var tickOpts = me.options.ticks; - - if (me.isHorizontal()) { - maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.width / 50)); - } else { - // The factor of 2 used to scale the font size has been experimentally determined. - var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, defaults.global.defaultFontSize); - maxTicks = Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(me.height / (2 * tickFontSize))); - } - - return maxTicks; - }, - // Called after the ticks are built. We need - handleDirectionalChanges: function() { - if (!this.isHorizontal()) { - // We are in a vertical orientation. The top value is the highest. So reverse the array - this.ticks.reverse(); - } - }, - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - // Utils - getPixelForValue: function(value) { - // This must be called after fit has been run so that - // this.left, this.top, this.right, and this.bottom have been defined - var me = this; - var start = me.start; - - var rightValue = +me.getRightValue(value); - var pixel; - var range = me.end - start; - - if (me.isHorizontal()) { - pixel = me.left + (me.width / range * (rightValue - start)); - } else { - pixel = me.bottom - (me.height / range * (rightValue - start)); - } - return pixel; - }, - getValueForPixel: function(pixel) { - var me = this; - var isHorizontal = me.isHorizontal(); - var innerDimension = isHorizontal ? me.width : me.height; - var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension; - return me.start + ((me.end - me.start) * offset); - }, - getPixelForTick: function(index) { - return this.getPixelForValue(this.ticksAsNumbers[index]); - } - }); - - scaleService.registerScaleType('linear', LinearScale, defaultConfig); -}; - -},{"26":26,"34":34,"35":35,"46":46}],56:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); -var Scale = require(33); - -/** - * Generate a set of linear ticks - * @param generationOptions the options used to generate the ticks - * @param dataRange the range of the data - * @returns {Array<Number>} array of tick values - */ -function generateTicks(generationOptions, dataRange) { - var ticks = []; - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var factor; - var precision; - var spacing; - - if (generationOptions.stepSize && generationOptions.stepSize > 0) { - spacing = generationOptions.stepSize; - } else { - var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false); - spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true); - - precision = generationOptions.precision; - if (precision !== undefined) { - // If the user specified a precision, round to that number of decimal places - factor = Math.pow(10, precision); - spacing = Math.ceil(spacing * factor) / factor; - } - } - var niceMin = Math.floor(dataRange.min / spacing) * spacing; - var niceMax = Math.ceil(dataRange.max / spacing) * spacing; - - // If min, max and stepSize is set and they make an evenly spaced scale use it. - if (!helpers.isNullOrUndef(generationOptions.min) && !helpers.isNullOrUndef(generationOptions.max) && generationOptions.stepSize) { - // If very close to our whole number, use it. - if (helpers.almostWhole((generationOptions.max - generationOptions.min) / generationOptions.stepSize, spacing / 1000)) { - niceMin = generationOptions.min; - niceMax = generationOptions.max; - } - } - - var numSpaces = (niceMax - niceMin) / spacing; - // If very close to our rounded value, use it. - if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { - numSpaces = Math.round(numSpaces); - } else { - numSpaces = Math.ceil(numSpaces); - } - - precision = 1; - if (spacing < 1) { - precision = Math.pow(10, 1 - Math.floor(helpers.log10(spacing))); - niceMin = Math.round(niceMin * precision) / precision; - niceMax = Math.round(niceMax * precision) / precision; - } - ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin); - for (var j = 1; j < numSpaces; ++j) { - ticks.push(Math.round((niceMin + j * spacing) * precision) / precision); - } - ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax); - - return ticks; -} - -module.exports = function(Chart) { - - var noop = helpers.noop; - - Chart.LinearScaleBase = Scale.extend({ - getRightValue: function(value) { - if (typeof value === 'string') { - return +value; - } - return Scale.prototype.getRightValue.call(this, value); - }, - - handleTickRangeOptions: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (tickOpts.beginAtZero) { - var minSign = helpers.sign(me.min); - var maxSign = helpers.sign(me.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - me.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the bottom down to 0 - me.min = 0; - } - } - - var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined; - var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined; - - if (tickOpts.min !== undefined) { - me.min = tickOpts.min; - } else if (tickOpts.suggestedMin !== undefined) { - if (me.min === null) { - me.min = tickOpts.suggestedMin; - } else { - me.min = Math.min(me.min, tickOpts.suggestedMin); - } - } - - if (tickOpts.max !== undefined) { - me.max = tickOpts.max; - } else if (tickOpts.suggestedMax !== undefined) { - if (me.max === null) { - me.max = tickOpts.suggestedMax; - } else { - me.max = Math.max(me.max, tickOpts.suggestedMax); - } - } - - if (setMin !== setMax) { - // We set the min or the max but not both. - // So ensure that our range is good - // Inverted or 0 length range can happen when - // ticks.min is set, and no datasets are visible - if (me.min >= me.max) { - if (setMin) { - me.max = me.min + 1; - } else { - me.min = me.max - 1; - } - } - } - - if (me.min === me.max) { - me.max++; - - if (!tickOpts.beginAtZero) { - me.min--; - } - } - }, - getTickLimit: noop, - handleDirectionalChanges: noop, - - buildTicks: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph. Make sure we always have at least 2 ticks - var maxTicks = me.getTickLimit(); - maxTicks = Math.max(2, maxTicks); - - var numericGeneratorOptions = { - maxTicks: maxTicks, - min: tickOpts.min, - max: tickOpts.max, - precision: tickOpts.precision, - stepSize: helpers.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize) - }; - var ticks = me.ticks = generateTicks(numericGeneratorOptions, me); - - me.handleDirectionalChanges(); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - me.max = helpers.max(ticks); - me.min = helpers.min(ticks); - - if (tickOpts.reverse) { - ticks.reverse(); - - me.start = me.max; - me.end = me.min; - } else { - me.start = me.min; - me.end = me.max; - } - }, - convertTicksToLabels: function() { - var me = this; - me.ticksAsNumbers = me.ticks.slice(); - me.zeroLineIndex = me.ticks.indexOf(0); - - Scale.prototype.convertTicksToLabels.call(me); - } - }); -}; - -},{"33":33,"46":46}],57:[function(require,module,exports){ -'use strict'; - -var helpers = require(46); -var Scale = require(33); -var scaleService = require(34); -var Ticks = require(35); - -/** - * Generate a set of logarithmic ticks - * @param generationOptions the options used to generate the ticks - * @param dataRange the range of the data - * @returns {Array<Number>} array of tick values - */ -function generateTicks(generationOptions, dataRange) { - var ticks = []; - var valueOrDefault = helpers.valueOrDefault; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph - var tickVal = valueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min)))); - - var endExp = Math.floor(helpers.log10(dataRange.max)); - var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp)); - var exp, significand; - - if (tickVal === 0) { - exp = Math.floor(helpers.log10(dataRange.minNotZero)); - significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp)); - - ticks.push(tickVal); - tickVal = significand * Math.pow(10, exp); - } else { - exp = Math.floor(helpers.log10(tickVal)); - significand = Math.floor(tickVal / Math.pow(10, exp)); - } - var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; - - do { - ticks.push(tickVal); - - ++significand; - if (significand === 10) { - significand = 1; - ++exp; - precision = exp >= 0 ? 1 : precision; - } - - tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision; - } while (exp < endExp || (exp === endExp && significand < endSignificand)); - - var lastTick = valueOrDefault(generationOptions.max, tickVal); - ticks.push(lastTick); - - return ticks; -} - - -module.exports = function(Chart) { - - var defaultConfig = { - position: 'left', - - // label settings - ticks: { - callback: Ticks.formatters.logarithmic - } - }; - - var LogarithmicScale = Scale.extend({ - determineDataLimits: function() { - var me = this; - var opts = me.options; - var chart = me.chart; - var data = chart.data; - var datasets = data.datasets; - var isHorizontal = me.isHorizontal(); - function IDMatches(meta) { - return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; - } - - // Calculate Range - me.min = null; - me.max = null; - me.minNotZero = null; - - var hasStacks = opts.stacked; - if (hasStacks === undefined) { - helpers.each(datasets, function(dataset, datasetIndex) { - if (hasStacks) { - return; - } - - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && - meta.stack !== undefined) { - hasStacks = true; - } - }); - } - - if (opts.stacked || hasStacks) { - var valuesPerStack = {}; - - helpers.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - var key = [ - meta.type, - // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined - ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), - meta.stack - ].join('.'); - - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - if (valuesPerStack[key] === undefined) { - valuesPerStack[key] = []; - } - - helpers.each(dataset.data, function(rawValue, index) { - var values = valuesPerStack[key]; - var value = +me.getRightValue(rawValue); - // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { - return; - } - values[index] = values[index] || 0; - values[index] += value; - }); - } - }); - - helpers.each(valuesPerStack, function(valuesForType) { - if (valuesForType.length > 0) { - var minVal = helpers.min(valuesForType); - var maxVal = helpers.max(valuesForType); - me.min = me.min === null ? minVal : Math.min(me.min, minVal); - me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); - } - }); - - } else { - helpers.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { - return; - } - - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; - } - - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; - } - - if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) { - me.minNotZero = value; - } - }); - } - }); - } - - // Common base implementation to handle ticks.min, ticks.max - this.handleTickRangeOptions(); - }, - handleTickRangeOptions: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - var valueOrDefault = helpers.valueOrDefault; - var DEFAULT_MIN = 1; - var DEFAULT_MAX = 10; - - me.min = valueOrDefault(tickOpts.min, me.min); - me.max = valueOrDefault(tickOpts.max, me.max); - - if (me.min === me.max) { - if (me.min !== 0 && me.min !== null) { - me.min = Math.pow(10, Math.floor(helpers.log10(me.min)) - 1); - me.max = Math.pow(10, Math.floor(helpers.log10(me.max)) + 1); - } else { - me.min = DEFAULT_MIN; - me.max = DEFAULT_MAX; - } - } - if (me.min === null) { - me.min = Math.pow(10, Math.floor(helpers.log10(me.max)) - 1); - } - if (me.max === null) { - me.max = me.min !== 0 - ? Math.pow(10, Math.floor(helpers.log10(me.min)) + 1) - : DEFAULT_MAX; - } - if (me.minNotZero === null) { - if (me.min > 0) { - me.minNotZero = me.min; - } else if (me.max < 1) { - me.minNotZero = Math.pow(10, Math.floor(helpers.log10(me.max))); - } else { - me.minNotZero = DEFAULT_MIN; - } - } - }, - buildTicks: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - var reverse = !me.isHorizontal(); - - var generationOptions = { - min: tickOpts.min, - max: tickOpts.max - }; - var ticks = me.ticks = generateTicks(generationOptions, me); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - me.max = helpers.max(ticks); - me.min = helpers.min(ticks); - - if (tickOpts.reverse) { - reverse = !reverse; - me.start = me.max; - me.end = me.min; - } else { - me.start = me.min; - me.end = me.max; - } - if (reverse) { - ticks.reverse(); - } - }, - convertTicksToLabels: function() { - this.tickValues = this.ticks.slice(); - - Scale.prototype.convertTicksToLabels.call(this); - }, - // Get the correct tooltip label - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - getPixelForTick: function(index) { - return this.getPixelForValue(this.tickValues[index]); - }, - /** - * Returns the value of the first tick. - * @param {Number} value - The minimum not zero value. - * @return {Number} The first tick value. - * @private - */ - _getFirstTickValue: function(value) { - var exp = Math.floor(helpers.log10(value)); - var significand = Math.floor(value / Math.pow(10, exp)); - - return significand * Math.pow(10, exp); - }, - getPixelForValue: function(value) { - var me = this; - var reverse = me.options.ticks.reverse; - var log10 = helpers.log10; - var firstTickValue = me._getFirstTickValue(me.minNotZero); - var offset = 0; - var innerDimension, pixel, start, end, sign; - - value = +me.getRightValue(value); - if (reverse) { - start = me.end; - end = me.start; - sign = -1; - } else { - start = me.start; - end = me.end; - sign = 1; - } - if (me.isHorizontal()) { - innerDimension = me.width; - pixel = reverse ? me.right : me.left; - } else { - innerDimension = me.height; - sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0) - pixel = reverse ? me.top : me.bottom; - } - if (value !== start) { - if (start === 0) { // include zero tick - offset = helpers.getValueOrDefault( - me.options.ticks.fontSize, - Chart.defaults.global.defaultFontSize - ); - innerDimension -= offset; - start = firstTickValue; - } - if (value !== 0) { - offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start)); - } - pixel += sign * offset; - } - return pixel; - }, - getValueForPixel: function(pixel) { - var me = this; - var reverse = me.options.ticks.reverse; - var log10 = helpers.log10; - var firstTickValue = me._getFirstTickValue(me.minNotZero); - var innerDimension, start, end, value; - - if (reverse) { - start = me.end; - end = me.start; - } else { - start = me.start; - end = me.end; - } - if (me.isHorizontal()) { - innerDimension = me.width; - value = reverse ? me.right - pixel : pixel - me.left; - } else { - innerDimension = me.height; - value = reverse ? pixel - me.top : me.bottom - pixel; - } - if (value !== start) { - if (start === 0) { // include zero tick - var offset = helpers.getValueOrDefault( - me.options.ticks.fontSize, - Chart.defaults.global.defaultFontSize - ); - value -= offset; - innerDimension -= offset; - start = firstTickValue; - } - value *= log10(end) - log10(start); - value /= innerDimension; - value = Math.pow(10, log10(start) + value); - } - return value; - } - }); - - scaleService.registerScaleType('logarithmic', LogarithmicScale, defaultConfig); -}; - -},{"33":33,"34":34,"35":35,"46":46}],58:[function(require,module,exports){ -'use strict'; - -var defaults = require(26); -var helpers = require(46); -var scaleService = require(34); -var Ticks = require(35); - -module.exports = function(Chart) { - - var globalDefaults = defaults.global; - - var defaultConfig = { - display: true, - - // Boolean - Whether to animate scaling the chart from the centre - animate: true, - position: 'chartArea', - - angleLines: { - display: true, - color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1 - }, - - gridLines: { - circular: false - }, - - // label settings - ticks: { - // Boolean - Show a backdrop to the scale label - showLabelBackdrop: true, - - // String - The colour of the label backdrop - backdropColor: 'rgba(255,255,255,0.75)', - - // Number - The backdrop padding above & below the label in pixels - backdropPaddingY: 2, - - // Number - The backdrop padding to the side of the label in pixels - backdropPaddingX: 2, - - callback: Ticks.formatters.linear - }, - - pointLabels: { - // Boolean - if true, show point labels - display: true, - - // Number - Point label font size in pixels - fontSize: 10, - - // Function - Used to convert point labels - callback: function(label) { - return label; - } - } - }; - - function getValueCount(scale) { - var opts = scale.options; - return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0; - } - - function getPointLabelFontOptions(scale) { - var pointLabelOptions = scale.options.pointLabels; - var fontSize = helpers.valueOrDefault(pointLabelOptions.fontSize, globalDefaults.defaultFontSize); - var fontStyle = helpers.valueOrDefault(pointLabelOptions.fontStyle, globalDefaults.defaultFontStyle); - var fontFamily = helpers.valueOrDefault(pointLabelOptions.fontFamily, globalDefaults.defaultFontFamily); - var font = helpers.fontString(fontSize, fontStyle, fontFamily); - - return { - size: fontSize, - style: fontStyle, - family: fontFamily, - font: font - }; - } - - function measureLabelSize(ctx, fontSize, label) { - if (helpers.isArray(label)) { - return { - w: helpers.longestText(ctx, ctx.font, label), - h: (label.length * fontSize) + ((label.length - 1) * 1.5 * fontSize) - }; - } - - return { - w: ctx.measureText(label).width, - h: fontSize - }; - } - - function determineLimits(angle, pos, size, min, max) { - if (angle === min || angle === max) { - return { - start: pos - (size / 2), - end: pos + (size / 2) - }; - } else if (angle < min || angle > max) { - return { - start: pos - size - 5, - end: pos - }; - } - - return { - start: pos, - end: pos + size + 5 - }; - } - - /** - * Helper function to fit a radial linear scale with point labels - */ - function fitWithPointLabels(scale) { - /* - * Right, this is really confusing and there is a lot of maths going on here - * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 - * - * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif - * - * Solution: - * - * We assume the radius of the polygon is half the size of the canvas at first - * at each index we check if the text overlaps. - * - * Where it does, we store that angle and that index. - * - * After finding the largest index and angle we calculate how much we need to remove - * from the shape radius to move the point inwards by that x. - * - * We average the left and right distances to get the maximum shape radius that can fit in the box - * along with labels. - * - * Once we have that, we can find the centre point for the chart, by taking the x text protrusion - * on each side, removing that from the size, halving it and adding the left x protrusion width. - * - * This will mean we have a shape fitted to the canvas, as large as it can be with the labels - * and position it in the most space efficient manner - * - * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif - */ - - var plFont = getPointLabelFontOptions(scale); - - // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. - // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points - var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2); - var furthestLimits = { - r: scale.width, - l: 0, - t: scale.height, - b: 0 - }; - var furthestAngles = {}; - var i, textSize, pointPosition; - - scale.ctx.font = plFont.font; - scale._pointLabelSizes = []; - - var valueCount = getValueCount(scale); - for (i = 0; i < valueCount; i++) { - pointPosition = scale.getPointPosition(i, largestPossibleRadius); - textSize = measureLabelSize(scale.ctx, plFont.size, scale.pointLabels[i] || ''); - scale._pointLabelSizes[i] = textSize; - - // Add quarter circle to make degree 0 mean top of circle - var angleRadians = scale.getIndexAngle(i); - var angle = helpers.toDegrees(angleRadians) % 360; - var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); - var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); - - if (hLimits.start < furthestLimits.l) { - furthestLimits.l = hLimits.start; - furthestAngles.l = angleRadians; - } - - if (hLimits.end > furthestLimits.r) { - furthestLimits.r = hLimits.end; - furthestAngles.r = angleRadians; - } - - if (vLimits.start < furthestLimits.t) { - furthestLimits.t = vLimits.start; - furthestAngles.t = angleRadians; - } - - if (vLimits.end > furthestLimits.b) { - furthestLimits.b = vLimits.end; - furthestAngles.b = angleRadians; - } - } - - scale.setReductions(largestPossibleRadius, furthestLimits, furthestAngles); - } - - /** - * Helper function to fit a radial linear scale with no point labels - */ - function fit(scale) { - var largestPossibleRadius = Math.min(scale.height / 2, scale.width / 2); - scale.drawingArea = Math.round(largestPossibleRadius); - scale.setCenterPoint(0, 0, 0, 0); - } - - function getTextAlignForAngle(angle) { - if (angle === 0 || angle === 180) { - return 'center'; - } else if (angle < 180) { - return 'left'; - } - - return 'right'; - } - - function fillText(ctx, text, position, fontSize) { - if (helpers.isArray(text)) { - var y = position.y; - var spacing = 1.5 * fontSize; - - for (var i = 0; i < text.length; ++i) { - ctx.fillText(text[i], position.x, y); - y += spacing; - } - } else { - ctx.fillText(text, position.x, position.y); - } - } - - function adjustPointPositionForLabelHeight(angle, textSize, position) { - if (angle === 90 || angle === 270) { - position.y -= (textSize.h / 2); - } else if (angle > 270 || angle < 90) { - position.y -= textSize.h; - } - } - - function drawPointLabels(scale) { - var ctx = scale.ctx; - var opts = scale.options; - var angleLineOpts = opts.angleLines; - var pointLabelOpts = opts.pointLabels; - - ctx.lineWidth = angleLineOpts.lineWidth; - ctx.strokeStyle = angleLineOpts.color; - - var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max); - - // Point Label Font - var plFont = getPointLabelFontOptions(scale); - - ctx.textBaseline = 'top'; - - for (var i = getValueCount(scale) - 1; i >= 0; i--) { - if (angleLineOpts.display) { - var outerPosition = scale.getPointPosition(i, outerDistance); - ctx.beginPath(); - ctx.moveTo(scale.xCenter, scale.yCenter); - ctx.lineTo(outerPosition.x, outerPosition.y); - ctx.stroke(); - ctx.closePath(); - } - - if (pointLabelOpts.display) { - // Extra 3px out for some label spacing - var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5); - - // Keep this in loop since we may support array properties here - var pointLabelFontColor = helpers.valueAtIndexOrDefault(pointLabelOpts.fontColor, i, globalDefaults.defaultFontColor); - ctx.font = plFont.font; - ctx.fillStyle = pointLabelFontColor; - - var angleRadians = scale.getIndexAngle(i); - var angle = helpers.toDegrees(angleRadians); - ctx.textAlign = getTextAlignForAngle(angle); - adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition); - fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.size); - } - } - } - - function drawRadiusLine(scale, gridLineOpts, radius, index) { - var ctx = scale.ctx; - ctx.strokeStyle = helpers.valueAtIndexOrDefault(gridLineOpts.color, index - 1); - ctx.lineWidth = helpers.valueAtIndexOrDefault(gridLineOpts.lineWidth, index - 1); - - if (scale.options.gridLines.circular) { - // Draw circular arcs between the points - ctx.beginPath(); - ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2); - ctx.closePath(); - ctx.stroke(); - } else { - // Draw straight lines connecting each index - var valueCount = getValueCount(scale); - - if (valueCount === 0) { - return; - } - - ctx.beginPath(); - var pointPosition = scale.getPointPosition(0, radius); - ctx.moveTo(pointPosition.x, pointPosition.y); - - for (var i = 1; i < valueCount; i++) { - pointPosition = scale.getPointPosition(i, radius); - ctx.lineTo(pointPosition.x, pointPosition.y); - } - - ctx.closePath(); - ctx.stroke(); - } - } - - function numberOrZero(param) { - return helpers.isNumber(param) ? param : 0; - } - - var LinearRadialScale = Chart.LinearScaleBase.extend({ - setDimensions: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - // Set the unconstrained dimension before label rotation - me.width = me.maxWidth; - me.height = me.maxHeight; - me.xCenter = Math.round(me.width / 2); - me.yCenter = Math.round(me.height / 2); - - var minSize = helpers.min([me.height, me.width]); - var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); - me.drawingArea = opts.display ? (minSize / 2) - (tickFontSize / 2 + tickOpts.backdropPaddingY) : (minSize / 2); - }, - determineDataLimits: function() { - var me = this; - var chart = me.chart; - var min = Number.POSITIVE_INFINITY; - var max = Number.NEGATIVE_INFINITY; - - helpers.each(chart.data.datasets, function(dataset, datasetIndex) { - if (chart.isDatasetVisible(datasetIndex)) { - var meta = chart.getDatasetMeta(datasetIndex); - - helpers.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - min = Math.min(value, min); - max = Math.max(value, max); - }); - } - }); - - me.min = (min === Number.POSITIVE_INFINITY ? 0 : min); - me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max); - - // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero - me.handleTickRangeOptions(); - }, - getTickLimit: function() { - var tickOpts = this.options.ticks; - var tickFontSize = helpers.valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); - return Math.min(tickOpts.maxTicksLimit ? tickOpts.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize))); - }, - convertTicksToLabels: function() { - var me = this; - - Chart.LinearScaleBase.prototype.convertTicksToLabels.call(me); - - // Point labels - me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me); - }, - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - fit: function() { - if (this.options.pointLabels.display) { - fitWithPointLabels(this); - } else { - fit(this); - } - }, - /** - * Set radius reductions and determine new radius and center point - * @private - */ - setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) { - var me = this; - var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l); - var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r); - var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t); - var radiusReductionBottom = -Math.max(furthestLimits.b - me.height, 0) / Math.cos(furthestAngles.b); - - radiusReductionLeft = numberOrZero(radiusReductionLeft); - radiusReductionRight = numberOrZero(radiusReductionRight); - radiusReductionTop = numberOrZero(radiusReductionTop); - radiusReductionBottom = numberOrZero(radiusReductionBottom); - - me.drawingArea = Math.min( - Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2), - Math.round(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)); - me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom); - }, - setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) { - var me = this; - var maxRight = me.width - rightMovement - me.drawingArea; - var maxLeft = leftMovement + me.drawingArea; - var maxTop = topMovement + me.drawingArea; - var maxBottom = me.height - bottomMovement - me.drawingArea; - - me.xCenter = Math.round(((maxLeft + maxRight) / 2) + me.left); - me.yCenter = Math.round(((maxTop + maxBottom) / 2) + me.top); - }, - - getIndexAngle: function(index) { - var angleMultiplier = (Math.PI * 2) / getValueCount(this); - var startAngle = this.chart.options && this.chart.options.startAngle ? - this.chart.options.startAngle : - 0; - - var startAngleRadians = startAngle * Math.PI * 2 / 360; - - // Start from the top instead of right, so remove a quarter of the circle - return index * angleMultiplier + startAngleRadians; - }, - getDistanceFromCenterForValue: function(value) { - var me = this; - - if (value === null) { - return 0; // null always in center - } - - // Take into account half font size + the yPadding of the top value - var scalingFactor = me.drawingArea / (me.max - me.min); - if (me.options.ticks.reverse) { - return (me.max - value) * scalingFactor; - } - return (value - me.min) * scalingFactor; - }, - getPointPosition: function(index, distanceFromCenter) { - var me = this; - var thisAngle = me.getIndexAngle(index) - (Math.PI / 2); - return { - x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + me.xCenter, - y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + me.yCenter - }; - }, - getPointPositionForValue: function(index, value) { - return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); - }, - - getBasePosition: function() { - var me = this; - var min = me.min; - var max = me.max; - - return me.getPointPositionForValue(0, - me.beginAtZero ? 0 : - min < 0 && max < 0 ? max : - min > 0 && max > 0 ? min : - 0); - }, - - draw: function() { - var me = this; - var opts = me.options; - var gridLineOpts = opts.gridLines; - var tickOpts = opts.ticks; - var valueOrDefault = helpers.valueOrDefault; - - if (opts.display) { - var ctx = me.ctx; - var startAngle = this.getIndexAngle(0); - - // Tick Font - var tickFontSize = valueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); - var tickFontStyle = valueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle); - var tickFontFamily = valueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - - helpers.each(me.ticks, function(label, index) { - // Don't draw a centre value (if it is minimum) - if (index > 0 || tickOpts.reverse) { - var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]); - - // Draw circular lines around the scale - if (gridLineOpts.display && index !== 0) { - drawRadiusLine(me, gridLineOpts, yCenterOffset, index); - } - - if (tickOpts.display) { - var tickFontColor = valueOrDefault(tickOpts.fontColor, globalDefaults.defaultFontColor); - ctx.font = tickLabelFont; - - ctx.save(); - ctx.translate(me.xCenter, me.yCenter); - ctx.rotate(startAngle); - - if (tickOpts.showLabelBackdrop) { - var labelWidth = ctx.measureText(label).width; - ctx.fillStyle = tickOpts.backdropColor; - ctx.fillRect( - -labelWidth / 2 - tickOpts.backdropPaddingX, - -yCenterOffset - tickFontSize / 2 - tickOpts.backdropPaddingY, - labelWidth + tickOpts.backdropPaddingX * 2, - tickFontSize + tickOpts.backdropPaddingY * 2 - ); - } - - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = tickFontColor; - ctx.fillText(label, 0, -yCenterOffset); - ctx.restore(); - } - } - }); - - if (opts.angleLines.display || opts.pointLabels.display) { - drawPointLabels(me); - } - } - } - }); - - scaleService.registerScaleType('radialLinear', LinearRadialScale, defaultConfig); -}; - -},{"26":26,"34":34,"35":35,"46":46}],59:[function(require,module,exports){ -/* global window: false */ -'use strict'; - -var moment = require(6); -moment = typeof moment === 'function' ? moment : window.moment; - -var defaults = require(26); -var helpers = require(46); -var Scale = require(33); -var scaleService = require(34); - -// Integer constants are from the ES6 spec. -var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; -var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; - -var INTERVALS = { - millisecond: { - common: true, - size: 1, - steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] - }, - second: { - common: true, - size: 1000, - steps: [1, 2, 5, 10, 15, 30] - }, - minute: { - common: true, - size: 60000, - steps: [1, 2, 5, 10, 15, 30] - }, - hour: { - common: true, - size: 3600000, - steps: [1, 2, 3, 6, 12] - }, - day: { - common: true, - size: 86400000, - steps: [1, 2, 5] - }, - week: { - common: false, - size: 604800000, - steps: [1, 2, 3, 4] - }, - month: { - common: true, - size: 2.628e9, - steps: [1, 2, 3] - }, - quarter: { - common: false, - size: 7.884e9, - steps: [1, 2, 3, 4] - }, - year: { - common: true, - size: 3.154e10 - } -}; - -var UNITS = Object.keys(INTERVALS); - -function sorter(a, b) { - return a - b; -} - -function arrayUnique(items) { - var hash = {}; - var out = []; - var i, ilen, item; - - for (i = 0, ilen = items.length; i < ilen; ++i) { - item = items[i]; - if (!hash[item]) { - hash[item] = true; - out.push(item); - } - } - - return out; -} - -/** - * Returns an array of {time, pos} objects used to interpolate a specific `time` or position - * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is - * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other - * extremity (left + width or top + height). Note that it would be more optimized to directly - * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need - * to create the lookup table. The table ALWAYS contains at least two items: min and max. - * - * @param {Number[]} timestamps - timestamps sorted from lowest to highest. - * @param {String} distribution - If 'linear', timestamps will be spread linearly along the min - * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}. - * If 'series', timestamps will be positioned at the same distance from each other. In this - * case, only timestamps that break the time linearity are registered, meaning that in the - * best case, all timestamps are linear, the table contains only min and max. - */ -function buildLookupTable(timestamps, min, max, distribution) { - if (distribution === 'linear' || !timestamps.length) { - return [ - {time: min, pos: 0}, - {time: max, pos: 1} - ]; - } - - var table = []; - var items = [min]; - var i, ilen, prev, curr, next; - - for (i = 0, ilen = timestamps.length; i < ilen; ++i) { - curr = timestamps[i]; - if (curr > min && curr < max) { - items.push(curr); - } - } - - items.push(max); - - for (i = 0, ilen = items.length; i < ilen; ++i) { - next = items[i + 1]; - prev = items[i - 1]; - curr = items[i]; - - // only add points that breaks the scale linearity - if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) { - table.push({time: curr, pos: i / (ilen - 1)}); - } - } - - return table; -} - -// @see adapted from http://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/ -function lookup(table, key, value) { - var lo = 0; - var hi = table.length - 1; - var mid, i0, i1; - - while (lo >= 0 && lo <= hi) { - mid = (lo + hi) >> 1; - i0 = table[mid - 1] || null; - i1 = table[mid]; - - if (!i0) { - // given value is outside table (before first item) - return {lo: null, hi: i1}; - } else if (i1[key] < value) { - lo = mid + 1; - } else if (i0[key] > value) { - hi = mid - 1; - } else { - return {lo: i0, hi: i1}; - } - } - - // given value is outside table (after last item) - return {lo: i1, hi: null}; -} - -/** - * Linearly interpolates the given source `value` using the table items `skey` values and - * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos') - * returns the position for a timestamp equal to 42. If value is out of bounds, values at - * index [0, 1] or [n - 1, n] are used for the interpolation. - */ -function interpolate(table, skey, sval, tkey) { - var range = lookup(table, skey, sval); - - // Note: the lookup table ALWAYS contains at least 2 items (min and max) - var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo; - var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi; - - var span = next[skey] - prev[skey]; - var ratio = span ? (sval - prev[skey]) / span : 0; - var offset = (next[tkey] - prev[tkey]) * ratio; - - return prev[tkey] + offset; -} - -/** - * Convert the given value to a moment object using the given time options. - * @see http://momentjs.com/docs/#/parsing/ - */ -function momentify(value, options) { - var parser = options.parser; - var format = options.parser || options.format; - - if (typeof parser === 'function') { - return parser(value); - } - - if (typeof value === 'string' && typeof format === 'string') { - return moment(value, format); - } - - if (!(value instanceof moment)) { - value = moment(value); - } - - if (value.isValid()) { - return value; - } - - // Labels are in an incompatible moment format and no `parser` has been provided. - // The user might still use the deprecated `format` option to convert his inputs. - if (typeof format === 'function') { - return format(value); - } - - return value; -} - -function parse(input, scale) { - if (helpers.isNullOrUndef(input)) { - return null; - } - - var options = scale.options.time; - var value = momentify(scale.getRightValue(input), options); - if (!value.isValid()) { - return null; - } - - if (options.round) { - value.startOf(options.round); - } - - return value.valueOf(); -} - -/** - * Returns the number of unit to skip to be able to display up to `capacity` number of ticks - * in `unit` for the given `min` / `max` range and respecting the interval steps constraints. - */ -function determineStepSize(min, max, unit, capacity) { - var range = max - min; - var interval = INTERVALS[unit]; - var milliseconds = interval.size; - var steps = interval.steps; - var i, ilen, factor; - - if (!steps) { - return Math.ceil(range / (capacity * milliseconds)); - } - - for (i = 0, ilen = steps.length; i < ilen; ++i) { - factor = steps[i]; - if (Math.ceil(range / (milliseconds * factor)) <= capacity) { - break; - } - } - - return factor; -} - -/** - * Figures out what unit results in an appropriate number of auto-generated ticks - */ -function determineUnitForAutoTicks(minUnit, min, max, capacity) { - var ilen = UNITS.length; - var i, interval, factor; - - for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) { - interval = INTERVALS[UNITS[i]]; - factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER; - - if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { - return UNITS[i]; - } - } - - return UNITS[ilen - 1]; -} - -/** - * Figures out what unit to format a set of ticks with - */ -function determineUnitForFormatting(ticks, minUnit, min, max) { - var duration = moment.duration(moment(max).diff(moment(min))); - var ilen = UNITS.length; - var i, unit; - - for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) { - unit = UNITS[i]; - if (INTERVALS[unit].common && duration.as(unit) >= ticks.length) { - return unit; - } - } - - return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; -} - -function determineMajorUnit(unit) { - for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) { - if (INTERVALS[UNITS[i]].common) { - return UNITS[i]; - } - } -} - -/** - * Generates a maximum of `capacity` timestamps between min and max, rounded to the - * `minor` unit, aligned on the `major` unit and using the given scale time `options`. - * Important: this method can return ticks outside the min and max range, it's the - * responsibility of the calling code to clamp values if needed. - */ -function generate(min, max, capacity, options) { - var timeOpts = options.time; - var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity); - var major = determineMajorUnit(minor); - var stepSize = helpers.valueOrDefault(timeOpts.stepSize, timeOpts.unitStepSize); - var weekday = minor === 'week' ? timeOpts.isoWeekday : false; - var majorTicksEnabled = options.ticks.major.enabled; - var interval = INTERVALS[minor]; - var first = moment(min); - var last = moment(max); - var ticks = []; - var time; - - if (!stepSize) { - stepSize = determineStepSize(min, max, minor, capacity); - } - - // For 'week' unit, handle the first day of week option - if (weekday) { - first = first.isoWeekday(weekday); - last = last.isoWeekday(weekday); - } - - // Align first/last ticks on unit - first = first.startOf(weekday ? 'day' : minor); - last = last.startOf(weekday ? 'day' : minor); - - // Make sure that the last tick include max - if (last < max) { - last.add(1, minor); - } - - time = moment(first); - - if (majorTicksEnabled && major && !weekday && !timeOpts.round) { - // Align the first tick on the previous `minor` unit aligned on the `major` unit: - // we first aligned time on the previous `major` unit then add the number of full - // stepSize there is between first and the previous major time. - time.startOf(major); - time.add(~~((first - time) / (interval.size * stepSize)) * stepSize, minor); - } - - for (; time < last; time.add(stepSize, minor)) { - ticks.push(+time); - } - - ticks.push(+time); - - return ticks; -} - -/** - * Returns the right and left offsets from edges in the form of {left, right}. - * Offsets are added when the `offset` option is true. - */ -function computeOffsets(table, ticks, min, max, options) { - var left = 0; - var right = 0; - var upper, lower; - - if (options.offset && ticks.length) { - if (!options.time.min) { - upper = ticks.length > 1 ? ticks[1] : max; - lower = ticks[0]; - left = ( - interpolate(table, 'time', upper, 'pos') - - interpolate(table, 'time', lower, 'pos') - ) / 2; - } - if (!options.time.max) { - upper = ticks[ticks.length - 1]; - lower = ticks.length > 1 ? ticks[ticks.length - 2] : min; - right = ( - interpolate(table, 'time', upper, 'pos') - - interpolate(table, 'time', lower, 'pos') - ) / 2; - } - } - - return {left: left, right: right}; -} - -function ticksFromTimestamps(values, majorUnit) { - var ticks = []; - var i, ilen, value, major; - - for (i = 0, ilen = values.length; i < ilen; ++i) { - value = values[i]; - major = majorUnit ? value === +moment(value).startOf(majorUnit) : false; - - ticks.push({ - value: value, - major: major - }); - } - - return ticks; -} - -function determineLabelFormat(data, timeOpts) { - var i, momentDate, hasTime; - var ilen = data.length; - - // find the label with the most parts (milliseconds, minutes, etc.) - // format all labels with the same level of detail as the most specific label - for (i = 0; i < ilen; i++) { - momentDate = momentify(data[i], timeOpts); - if (momentDate.millisecond() !== 0) { - return 'MMM D, YYYY h:mm:ss.SSS a'; - } - if (momentDate.second() !== 0 || momentDate.minute() !== 0 || momentDate.hour() !== 0) { - hasTime = true; - } - } - if (hasTime) { - return 'MMM D, YYYY h:mm:ss a'; - } - return 'MMM D, YYYY'; -} - -module.exports = function() { - - var defaultConfig = { - position: 'bottom', - - /** - * Data distribution along the scale: - * - 'linear': data are spread according to their time (distances can vary), - * - 'series': data are spread at the same distance from each other. - * @see https://github.com/chartjs/Chart.js/pull/4507 - * @since 2.7.0 - */ - distribution: 'linear', - - /** - * Scale boundary strategy (bypassed by min/max time options) - * - `data`: make sure data are fully visible, ticks outside are removed - * - `ticks`: make sure ticks are fully visible, data outside are truncated - * @see https://github.com/chartjs/Chart.js/pull/4556 - * @since 2.7.0 - */ - bounds: 'data', - - time: { - parser: false, // false == a pattern string from http://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment - format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from http://momentjs.com/docs/#/parsing/string-format/ - unit: false, // false == automatic or override with week, month, year, etc. - round: false, // none, or override with week, month, year, etc. - displayFormat: false, // DEPRECATED - isoWeekday: false, // override week start day - see http://momentjs.com/docs/#/get-set/iso-weekday/ - minUnit: 'millisecond', - - // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/ - displayFormats: { - millisecond: 'h:mm:ss.SSS a', // 11:20:01.123 AM, - second: 'h:mm:ss a', // 11:20:01 AM - minute: 'h:mm a', // 11:20 AM - hour: 'hA', // 5PM - day: 'MMM D', // Sep 4 - week: 'll', // Week 46, or maybe "[W]WW - YYYY" ? - month: 'MMM YYYY', // Sept 2015 - quarter: '[Q]Q - YYYY', // Q3 - year: 'YYYY' // 2015 - }, - }, - ticks: { - autoSkip: false, - - /** - * Ticks generation input values: - * - 'auto': generates "optimal" ticks based on scale size and time options. - * - 'data': generates ticks from data (including labels from data {t|x|y} objects). - * - 'labels': generates ticks from user given `data.labels` values ONLY. - * @see https://github.com/chartjs/Chart.js/pull/4507 - * @since 2.7.0 - */ - source: 'auto', - - major: { - enabled: false - } - } - }; - - var TimeScale = Scale.extend({ - initialize: function() { - if (!moment) { - throw new Error('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com'); - } - - this.mergeTicksOptions(); - - Scale.prototype.initialize.call(this); - }, - - update: function() { - var me = this; - var options = me.options; - - // DEPRECATIONS: output a message only one time per update - if (options.time && options.time.format) { - console.warn('options.time.format is deprecated and replaced by options.time.parser.'); - } - - return Scale.prototype.update.apply(me, arguments); - }, - - /** - * Allows data to be referenced via 't' attribute - */ - getRightValue: function(rawValue) { - if (rawValue && rawValue.t !== undefined) { - rawValue = rawValue.t; - } - return Scale.prototype.getRightValue.call(this, rawValue); - }, - - determineDataLimits: function() { - var me = this; - var chart = me.chart; - var timeOpts = me.options.time; - var unit = timeOpts.unit || 'day'; - var min = MAX_INTEGER; - var max = MIN_INTEGER; - var timestamps = []; - var datasets = []; - var labels = []; - var i, j, ilen, jlen, data, timestamp; - - // Convert labels to timestamps - for (i = 0, ilen = chart.data.labels.length; i < ilen; ++i) { - labels.push(parse(chart.data.labels[i], me)); - } - - // Convert data to timestamps - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - if (chart.isDatasetVisible(i)) { - data = chart.data.datasets[i].data; - - // Let's consider that all data have the same format. - if (helpers.isObject(data[0])) { - datasets[i] = []; - - for (j = 0, jlen = data.length; j < jlen; ++j) { - timestamp = parse(data[j], me); - timestamps.push(timestamp); - datasets[i][j] = timestamp; - } - } else { - timestamps.push.apply(timestamps, labels); - datasets[i] = labels.slice(0); - } - } else { - datasets[i] = []; - } - } - - if (labels.length) { - // Sort labels **after** data have been converted - labels = arrayUnique(labels).sort(sorter); - min = Math.min(min, labels[0]); - max = Math.max(max, labels[labels.length - 1]); - } - - if (timestamps.length) { - timestamps = arrayUnique(timestamps).sort(sorter); - min = Math.min(min, timestamps[0]); - max = Math.max(max, timestamps[timestamps.length - 1]); - } - - min = parse(timeOpts.min, me) || min; - max = parse(timeOpts.max, me) || max; - - // In case there is no valid min/max, set limits based on unit time option - min = min === MAX_INTEGER ? +moment().startOf(unit) : min; - max = max === MIN_INTEGER ? +moment().endOf(unit) + 1 : max; - - // Make sure that max is strictly higher than min (required by the lookup table) - me.min = Math.min(min, max); - me.max = Math.max(min + 1, max); - - // PRIVATE - me._horizontal = me.isHorizontal(); - me._table = []; - me._timestamps = { - data: timestamps, - datasets: datasets, - labels: labels - }; - }, - - buildTicks: function() { - var me = this; - var min = me.min; - var max = me.max; - var options = me.options; - var timeOpts = options.time; - var timestamps = []; - var ticks = []; - var i, ilen, timestamp; - - switch (options.ticks.source) { - case 'data': - timestamps = me._timestamps.data; - break; - case 'labels': - timestamps = me._timestamps.labels; - break; - case 'auto': - default: - timestamps = generate(min, max, me.getLabelCapacity(min), options); - } - - if (options.bounds === 'ticks' && timestamps.length) { - min = timestamps[0]; - max = timestamps[timestamps.length - 1]; - } - - // Enforce limits with user min/max options - min = parse(timeOpts.min, me) || min; - max = parse(timeOpts.max, me) || max; - - // Remove ticks outside the min/max range - for (i = 0, ilen = timestamps.length; i < ilen; ++i) { - timestamp = timestamps[i]; - if (timestamp >= min && timestamp <= max) { - ticks.push(timestamp); - } - } - - me.min = min; - me.max = max; - - // PRIVATE - me._unit = timeOpts.unit || determineUnitForFormatting(ticks, timeOpts.minUnit, me.min, me.max); - me._majorUnit = determineMajorUnit(me._unit); - me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution); - me._offsets = computeOffsets(me._table, ticks, min, max, options); - me._labelFormat = determineLabelFormat(me._timestamps.data, timeOpts); - - return ticksFromTimestamps(ticks, me._majorUnit); - }, - - getLabelForIndex: function(index, datasetIndex) { - var me = this; - var data = me.chart.data; - var timeOpts = me.options.time; - var label = data.labels && index < data.labels.length ? data.labels[index] : ''; - var value = data.datasets[datasetIndex].data[index]; - - if (helpers.isObject(value)) { - label = me.getRightValue(value); - } - if (timeOpts.tooltipFormat) { - return momentify(label, timeOpts).format(timeOpts.tooltipFormat); - } - if (typeof label === 'string') { - return label; - } - - return momentify(label, timeOpts).format(me._labelFormat); - }, - - /** - * Function to format an individual tick mark - * @private - */ - tickFormatFunction: function(tick, index, ticks, formatOverride) { - var me = this; - var options = me.options; - var time = tick.valueOf(); - var formats = options.time.displayFormats; - var minorFormat = formats[me._unit]; - var majorUnit = me._majorUnit; - var majorFormat = formats[majorUnit]; - var majorTime = tick.clone().startOf(majorUnit).valueOf(); - var majorTickOpts = options.ticks.major; - var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime; - var label = tick.format(formatOverride ? formatOverride : major ? majorFormat : minorFormat); - var tickOpts = major ? majorTickOpts : options.ticks.minor; - var formatter = helpers.valueOrDefault(tickOpts.callback, tickOpts.userCallback); - - return formatter ? formatter(label, index, ticks) : label; - }, - - convertTicksToLabels: function(ticks) { - var labels = []; - var i, ilen; - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - labels.push(this.tickFormatFunction(moment(ticks[i].value), i, ticks)); - } - - return labels; - }, - - /** - * @private - */ - getPixelForOffset: function(time) { - var me = this; - var size = me._horizontal ? me.width : me.height; - var start = me._horizontal ? me.left : me.top; - var pos = interpolate(me._table, 'time', time, 'pos'); - - return start + size * (me._offsets.left + pos) / (me._offsets.left + 1 + me._offsets.right); - }, - - getPixelForValue: function(value, index, datasetIndex) { - var me = this; - var time = null; - - if (index !== undefined && datasetIndex !== undefined) { - time = me._timestamps.datasets[datasetIndex][index]; - } - - if (time === null) { - time = parse(value, me); - } - - if (time !== null) { - return me.getPixelForOffset(time); - } - }, - - getPixelForTick: function(index) { - var ticks = this.getTicks(); - return index >= 0 && index < ticks.length ? - this.getPixelForOffset(ticks[index].value) : - null; - }, - - getValueForPixel: function(pixel) { - var me = this; - var size = me._horizontal ? me.width : me.height; - var start = me._horizontal ? me.left : me.top; - var pos = (size ? (pixel - start) / size : 0) * (me._offsets.left + 1 + me._offsets.left) - me._offsets.right; - var time = interpolate(me._table, 'pos', pos, 'time'); - - return moment(time); - }, - - /** - * Crude approximation of what the label width might be - * @private - */ - getLabelWidth: function(label) { - var me = this; - var ticksOpts = me.options.ticks; - var tickLabelWidth = me.ctx.measureText(label).width; - var angle = helpers.toRadians(ticksOpts.maxRotation); - var cosRotation = Math.cos(angle); - var sinRotation = Math.sin(angle); - var tickFontSize = helpers.valueOrDefault(ticksOpts.fontSize, defaults.global.defaultFontSize); - - return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation); - }, - - /** - * @private - */ - getLabelCapacity: function(exampleTime) { - var me = this; - - var formatOverride = me.options.time.displayFormats.millisecond; // Pick the longest format for guestimation - - var exampleLabel = me.tickFormatFunction(moment(exampleTime), 0, [], formatOverride); - var tickLabelWidth = me.getLabelWidth(exampleLabel); - var innerWidth = me.isHorizontal() ? me.width : me.height; - - var capacity = Math.floor(innerWidth / tickLabelWidth); - return capacity > 0 ? capacity : 1; - } - }); - - scaleService.registerScaleType('time', TimeScale, defaultConfig); -}; - -},{"26":26,"33":33,"34":34,"46":46,"6":6}]},{},[7])(7) -}); diff --git a/web/src/main/resources/static/js/pdxFinder.js b/web/src/main/resources/static/js/pdxFinder.js index 851185c668e0c2007a6d54b6f5fc130f0c9160a8..c414c078ed917e241ba6f8b7236f9a5226e52ef0 100644 --- a/web/src/main/resources/static/js/pdxFinder.js +++ b/web/src/main/resources/static/js/pdxFinder.js @@ -466,23 +466,23 @@ function getMolecularDataTable(clickedLink, clickedData) { /* <br> - <span class="small"> - <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" + Â <span class="small"> + Â <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" style="text-decoration:none; color:#06369d; text-transform: lowercase;"> civic - <i class="icon icon-generic" data-icon="x"> </i> - </a> + Â <i class="icon icon-generic" data-icon="x"> </i> + Â </a> </span> <span class="small"> - <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" + Â <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" style="text-decoration:none; color:#06369d; text-transform: lowercase;"> cosmic - <i class="icon icon-generic" data-icon="x"> </i> - </a> + Â <i class="icon icon-generic" data-icon="x"> </i> + Â </a> </span> <span class="small"> - <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" + Â <a target="_blank" href="https://civicdb.org/events/genes/24/summary#gene" style="text-decoration:none; color:#06369d; text-transform: lowercase;"> cravat - <i class="icon icon-generic" data-icon="x"> </i> - </a> + Â <i class="icon icon-generic" data-icon="x"> </i> + Â </a> </span> */ @@ -497,7 +497,7 @@ function displayMolecularDataTable(tableData, clickedData) { var theadRow = jQuery('<tr>'); var tbody = jQuery('<tbody />'); - if (dataVisibility === true) { + if (dataVisibility === true && fullData.length > 1) { let oneData = fullData[0]; let tableHeaders = Object.keys(oneData); @@ -528,13 +528,16 @@ function displayMolecularDataTable(tableData, clickedData) { table.append(tbody); targetDiv.append(table); customizeDatatable('molcharDataTable', clickedData[4]); - } else { - + } + else { let report = `<b style="margin-top: 15px; font-size: 13px; color: #06369d;"> ${tableData.reports[0]} </b> ` targetDiv.append(report); - $('#download-data').hide(); + if(dataVisibility === false){ + $('#download-data').hide(); + } } + $("#omicDataCount").html(rowCount); $("#clickedSampleId").html(clickedData[0]); $("#modelHistology").html(clickedData[1]); @@ -596,4 +599,8 @@ function customizeDatatable(dTable, presentData) { oTable.search($(this).val()).draw(); }) +} + +function openNewWindow(url){ + window.open(url,'_blank'); } \ No newline at end of file diff --git a/web/src/main/resources/templates/details.html b/web/src/main/resources/templates/details.html index d0b0879c2c4f56222939e7e802c11a40835c9bff..f25ef162fb04eec5d47ca2b7fe7f5c9b856fbd63 100644 --- a/web/src/main/resources/templates/details.html +++ b/web/src/main/resources/templates/details.html @@ -78,624 +78,644 @@ <th:block th:include="fragments/shared :: header"></th:block> - <div id="content-details"> + <div id="content"> + + <!-- Suggested layout containers --> - <section id="main-content-area" role="main"> - - <th:block th:include="fragments/shared :: breadcrumb-search-details"></th:block> - - <div id="details-content" class="row-main"> - <!-- Three Grids Section--> - <section> - <div id="detail-title" class="row"> - <div id="dt-left"> - <div class="columns medium-4 small-12 margin-top-30"> - <h4 class="pdxBig black"><span class="float-left" th:text="${data.providerName}"> The Jackson Laboratory </span> - </h4> - </div> - <div class="columns medium-4 small-12 margin-top-30"> - <h4 class="pdxBig"><span class="float-left border-color-black" - th:text="${data.modelId+': '+data.mappedOntologyTermLabel}"></span> - </h4> - </div> - </div> - <div id="dt-right"> - <div class="columns medium-4 small-12 shiftUp20"> - <!-- - <a th:href="@{'mailto:'+${data.contactProviderUrl+'?subject='+data.modelId}}" - th:if="${ data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'@')}"> - <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> - </a> - --> - - <a th:href="@{'mailto:'+${data.contactProviderUrl+'?subject='+data.modelId}}" - th:if="${data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'@')}"> - <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> - </a> - - <a th:href="@{${data.contactProviderUrl}}" th:target="_blank" - th:if="${data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'http') }"> - <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> - </a> - - - - <a th:href="@{${data.viewDataAtUrl}}" th:target="_blank" - th:if="${data.viewDataAtUrl != null && #strings.contains(data.viewDataAtUrl,'http')}"> - <h4 class="button outline uppercase margin-top-large minwidth300 shiftUp10 card-3b" - th:text="${data.viewDataAtLabel}">View at Provider</h4> - </a> - - <a style="visibility: collapse;" th:href="@{'/pdx/'+${data.dataSource}+'/'+${data.modelId}+'/pdf'}" - th:target="_blank" - class="button outline uppercase margin-top-large minwidth300 shiftUp10 card-3b"> - <span> Download PDF <i class="icon icon-functional" data-icon="="></i> </span> - </a> + <section id="main-content-area" role="main" style="width: 1200px; margin: auto;"> + + <th:block th:include="fragments/shared :: breadcrumb-services"></th:block> + + <div class="row"> + <nav aria-label="You are here:" role="navigation"> + <ul class="breadcrumbs columns"> + <li><a href="/">Home</a></li> + <li> + Details + </li> + <li> + <span class="show-for-sr">Current: </span> <span th:text="${data.modelId}">Model ID</span> + </li> + </ul> + </nav> + </div> - </div> - </div> - <div class="reset-float"></div> + <!-- Three Grids Section--> + <section> + <div class="row"> + + <div class="columns medium-4 small-12 margin-top-30"> + <h4 class="pdxBig"><span class="float-left border-color-black" + th:text="${data.modelId+': '+data.mappedOntologyTermLabel}"></span> + </h4> </div> - </section> - <hr class="margin-vertical-20 line_v2"> + <div class="columns medium-4 small-12 margin-top-30" style="margin-top: 0px"> + <h4 class="pdxBig black"><span class="float-left" th:text="${data.providerName}"> The Jackson Laboratory </span> + </h4> + </div> - <!-- Tabs Section --> - <section class="row large-10 medium-12 expanded" id="detailsData"> - <div class="row large-12 medium-12 expanded"> - <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> + <div class="columns medium-4 small-12 shiftUp20"> + <!-- + <a th:href="@{'mailto:'+${data.contactProviderUrl+'?subject='+data.modelId}}" + th:if="${ data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'@')}"> + <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> + </a> + --> - <li class="tabs-title is-active"> - <a href="#summary" aria-selected="true" style="font-size: 15px; padding: 15px;"> PDX - Model </a> - </li> + <a th:href="@{'mailto:'+${data.contactProviderUrl+'?subject='+data.modelId}}" + th:if="${data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'@')}"> + <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> + </a> + <a th:href="@{${data.contactProviderUrl}}" th:target="_blank" + th:if="${data.contactProviderUrl != null && #strings.contains(data.contactProviderUrl,'http') }"> + <h4 class="button more uppercase margin-top-large minwidth300 card-3b">Contact Provider</h4> + </a> - <li class="tabs-title"> - <a href="#patients" style="font-size: 15px; padding: 15px;"> Patient </a> - </li> +<!-- + <a th:href="@{${data.viewDataAtUrl}}" th:target="_blank" + th:if="${data.viewDataAtUrl != null && #strings.contains(data.viewDataAtUrl,'http')}"> + <h4 class="button outline uppercase margin-top-large minwidth300 shiftUp10 card-3b" + th:text="${data.viewDataAtLabel}">View at Provider</h4> + </a> +--> +<!-- + <a th:href="@{'/pdx/'+${data.dataSource}+'/'+${data.modelId}+'/pdf'}" + th:target="_blank" + class="button outline uppercase margin-top-large minwidth300 shiftUp10 card-3b"> + <span> Download PDF <i class="icon icon-functional" data-icon="="></i> </span> + </a> +--> + </div> + </div> + </section> + <hr class="margin-vertical-20 line_v2"> - <li th:if="${ #lists.isEmpty(data.molecularDataRows)}" - class="tabs-title "> - <a href="#variation" style="font-size: 15px; padding: 15px;" id="variation_data_link" - onclick="initTabs('0')"> - Molecular Data (0) - </a> - </li> - <li th:if="${ not #lists.isEmpty(data.molecularDataRows) }" - class="tabs-title "> - <a href="#variation" style="font-size: 15px; padding: 15px;" id="variation_data_link" - onclick="initTabs('0')"> - Molecular Data - (<span th:text="${data.molecularDataEntrySize}"> ... </span>) - </a> - </li> + <!-- Tabs Section --> + <section class="row large-10 medium-12 expanded" id="detailsData" style="width:100%"> + <div class="row large-12 medium-12 expanded"> + <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> - <li th:if="${data.dosingStudyNumbers} == 0" class="tabs-title"> - <a href="#dosing_studies" style="font-size: 15px; padding: 15px;">Dosing study (0)</a> - </li> + <li class="tabs-title is-active"> + <a href="#summary" aria-selected="true" style="font-size: 15px; padding: 15px;"> PDX + Model </a> + </li> - <li th:if="${data.dosingStudyNumbers} > 0" class="tabs-title"> - <a href="#dosing_studies" style="font-size: 15px; padding: 15px;">Dosing study (1)</a> - </li> - </ul> - </div> + <li class="tabs-title"> + <a href="#patients" style="font-size: 15px; padding: 15px;"> Patient </a> + </li> - <div class="tabs-content style-2" data-tabs-content="example2-tabs"> - <div class="tabs-panel is-active" id="summary"> - <!-- Summary first row --> - <div class="row large-12 medium-12 expanded"> + <li th:if="${ #lists.isEmpty(data.molecularDataRows)}" + class="tabs-title "> + <a href="#variation" style="font-size: 15px; padding: 15px;" id="variation_data_link" + onclick="initTabs('0')"> + Molecular Data (0) + </a> + </li> - <div class="columns medium-12 small-12 margin-top-30 card-3"> - <div class="responsive-table top-space-20"> - <table class="datatable-pdx table-borderedPdx pdx-table head-left"> - <thead> - <tr> - <th colspan="2"> Related Models </th> - </tr> - </thead> - <tbody> - <tr th:if="${not #lists.isEmpty(data.relatedModels)}"> - <th class="text-left"> Models </th> - <td><span th:each="relMod:${data.relatedModels}"><a th:text="${relMod}" - th:href="@{'/pdx/'+${data.dataSource}+'/'+${relMod}}"></a> </span> - </td> - </tr> - </tbody> - </table> - </div> - </div> + <li th:if="${ not #lists.isEmpty(data.molecularDataRows) }" + class="tabs-title "> + <a href="#variation" style="font-size: 15px; padding: 15px;" id="variation_data_link" + onclick="initTabs('0')"> + Molecular Data + (<span th:text="${data.molecularDataEntrySize}"> ... </span>) + </a> + </li> - <div class="columns medium-12 small-12 margin-top-medium card-3"> - <div class="responsive-table top-space-20"> + <li th:if="${data.dosingStudyNumbers} == 0" class="tabs-title"> + <a href="#dosing_studies" style="font-size: 15px; padding: 15px;">Dosing study (0)</a> + </li> - <table class="datatable-pdx pdx-table table-borderedPdx head-left"> - <thead> - <tr> - <th colspan="6">PDX model Engraftment</th> - </tr> - <tr> - <th> Host Strain Name</th> - <th> Site</th> - <th> Type</th> - <th> Material</th> - <th> Material Status</th> - <th>Passage</th> - </tr> - </thead> - <tbody> - <tr th:each="pdxModel, iter : ${data.pdxModelList}"> - <td th:text="${pdxModel.strainName}"></td> - <td th:text="${pdxModel.engraftmentSite}" class="capt-text"></td> - <td th:text="${pdxModel.engraftmentType}" class="capt-text"></td> - <td th:text="${pdxModel.engraftmentMaterial}" class="capt-text"></td> - <td th:text="${pdxModel.engraftmentMaterialState}" class="capt-text"></td> - <td th:text="${pdxModel.passage}" class="capt-text"></td> - </tr> - </tbody> - </table> - </div> - </div> + <li th:if="${data.dosingStudyNumbers} > 0" class="tabs-title"> + <a href="#dosing_studies" style="font-size: 15px; padding: 15px;">Dosing study (1)</a> + </li> - <div class="columns medium-12 small-12 margin-top-medium card-3"> - <div class="responsive-table top-space-20"> + </ul> - <table class="datatable-pdx pdx-table table-borderedPdx head-left"> - <thead> - <tr> - <th colspan="3">Model Quality Control</th> - </tr> - <tr> - <th>Technique</th> - <th>Description</th> - <th>Passage</th> - </tr> - </thead> - <tbody> - <tr th:each="qa, iter : ${data.modelQualityControl}"> - <td th:text="${qa.technique}" class="capt-text"></td> - <td th:text="${qa.description}" class="capt-text"></td> - <td th:text="${qa.passage}" class="capt-text"></td> - </tr> - </tbody> - </table> - </div> + </div> + + <div class="tabs-content style-2" data-tabs-content="example2-tabs"> + <div class="tabs-panel is-active" id="summary"> + + + <!-- Summary first row --> + <div class="row large-12 medium-12 expanded"> + + <div class="columns medium-12 small-12 margin-top-30 card-3"> + <div class="responsive-table top-space-20"> + <table class="datatable-pdx table-borderedPdx pdx-table head-left"> + <thead> + <tr> + <th colspan="2"> Related Models </th> + </tr> + </thead> + <tbody> + <tr th:if="${not #lists.isEmpty(data.relatedModels)}"> + <th class="text-left"> Models </th> + <td><span th:each="relMod:${data.relatedModels}"><a th:text="${relMod}" + th:href="@{'/pdx/'+${data.dataSource}+'/'+${relMod}}"></a> </span> + </td> + </tr> + </tbody> + </table> </div> + </div> + <div class="columns medium-12 small-12 margin-top-medium card-3"> + <div class="responsive-table top-space-20"> + + <table class="datatable-pdx pdx-table table-borderedPdx head-left"> + <thead> + <tr> + <th colspan="6">PDX model Engraftment</th> + </tr> + <tr> + <th> Host Strain Name</th> + <th> Site</th> + <th> Type</th> + <th> Material</th> + <th> Material Status</th> + <th>Passage</th> + </tr> + </thead> + <tbody> + <tr th:each="pdxModel, iter : ${data.pdxModelList}"> + <td th:text="${pdxModel.strainName}"></td> + <td th:text="${pdxModel.engraftmentSite}" class="capt-text"></td> + <td th:text="${pdxModel.engraftmentType}" class="capt-text"></td> + <td th:text="${pdxModel.engraftmentMaterial}" class="capt-text"></td> + <td th:text="${pdxModel.engraftmentMaterialState}" class="capt-text"></td> + <td th:text="${pdxModel.passage}" class="capt-text"></td> + </tr> + </tbody> + </table> + </div> + + </div> - <div th:unless="${#lists.isEmpty(data.publications)}" - class="columns medium-12 small-12 margin-top-medium card-3"> - <div class="responsive-table top-space-20"> - <table th:each="pub, iter : ${data.publications}" class="datatable-pdx table-borderedPdx pdx-table head-left"> + <div class="columns medium-12 small-12 margin-top-medium card-3"> + <div class="responsive-table top-space-20"> + + <table class="datatable-pdx pdx-table table-borderedPdx head-left"> + <thead> + <tr> + <th colspan="3">Model Quality Control</th> + </tr> + <tr> + <th>Technique</th> + <th>Description</th> + <th>Passage</th> + </tr> + </thead> + <tbody> + <tr th:each="qa, iter : ${data.modelQualityControl}"> + <td th:text="${qa.technique}" class="capt-text"></td> + <td th:text="${qa.description}" class="capt-text"></td> + <td th:text="${qa.passage}" class="capt-text"></td> + </tr> + </tbody> + </table> + </div> - <thead th:if="${iter.index == 0}"> - <tr><th colspan="2"> Publications</th></tr> - </thead> + </div> - <tbody> - <tr> - <th class="text-left medium-2"> Title </th> - <td><a th:text="${#strings.capitalizeWords(pub.resultList.result[0].title)}" - th:href="| https://europepmc.org/article/MED/${pub.resultList.result[0].id} |" - target="_blank" - style="white-space: normal;"> Title Text <i class="icon icon-generic" data-icon="x"> </i> </a> - </td> - </tr> - <tr> - <th class="text-left medium-2">Authors</th> - <td th:text="${pub.resultList.result[0].authorString}">Bougherara H, NĂ©mati F, Nicolas A, ... Decaudin D.</td> - </tr> - <tr> - <th class="text-left medium-2">Publication year</th> - <td th:text="${pub.resultList.result[0].pubYear}"> 2017 </td> - </tr> - <tr> - <th class="text-left medium-2"> Journal</th> - <td th:text="${pub.resultList.result[0].title}"> Journal Title </td> - </tr> - <tr> - <td class="text-left" colspan="2"> - - <ul class="vertical menu" data-accordion-menu> - <li> - <a type="button" th:id="|publication-${iter.index}|" class="primary button card-3b small-2 bold" href="#"> - <span th:id="|btn-text-${iter.index}|"> SHOW ABSTRACT</span> <i class="icon icon-generic" data-icon="P"></i> - </a> - <ul class="menu vertical nested topSace10"> - <li> - <div class="callout card-3" style="white-space: normal; margin-left: -10px;" > - <p th:text="${pub.resultList.result[0].abstractText}"> </p> - </div> - </li> - </ul> - </li> - </ul> - - </td> - </tr> + <div th:unless="${#lists.isEmpty(data.publications)}" + class="columns medium-12 small-12 margin-top-medium card-3"> + <div class="responsive-table top-space-20"> + + <table th:each="pub, iter : ${data.publications}" class="datatable-pdx table-borderedPdx pdx-table head-left"> + + <thead th:if="${iter.index == 0}"> + <tr><th colspan="2"> Publications</th></tr> + </thead> + + <tbody> + <tr> + <th class="text-left medium-2"> Title </th> + <td><a th:text="${#strings.capitalizeWords(pub.resultList.result[0].title)}" + th:href="| https://europepmc.org/article/MED/${pub.resultList.result[0].id} |" + target="_blank" + style="white-space: normal;"> Title Text <i class="icon icon-generic" data-icon="x"> </i> </a> + </td> + </tr> + <tr> + <th class="text-left medium-2">Authors</th> + <td th:text="${pub.resultList.result[0].authorString}">Bougherara H, NĂ©mati F, Nicolas A, ... Decaudin D.</td> + </tr> + <tr> + <th class="text-left medium-2">Publication year</th> + <td th:text="${pub.resultList.result[0].pubYear}"> 2017 </td> + </tr> + <tr> + <th class="text-left medium-2"> Journal</th> + <td th:text="${pub.resultList.result[0].title}"> Journal Title </td> + </tr> + + + <tr> + <td class="text-left" colspan="2"> + + <ul class="vertical menu" data-accordion-menu> + <li> + <a type="button" th:id="|publication-${iter.index}|" class="primary button card-3b small-2 bold" href="#"> + <span th:id="|btn-text-${iter.index}|"> SHOW ABSTRACT</span> <i class="icon icon-generic" data-icon="P"></i> + </a> + <ul class="menu vertical nested topSace10"> + <li> + <div class="callout card-3" style="white-space: normal; margin-left: -10px;" > + <p th:text="${pub.resultList.result[0].abstractText}"> </p> + </div> + </li> + </ul> + </li> + </ul> - </tbody> - </table> + </td> + </tr> - </div> - </div> + </tbody> + </table> + </div> </div> + </div> + </div> - <div class="tabs-panel" id="patients"> + <div class="tabs-panel" id="patients"> + + <section class="row large-12 medium-12 expanded" id="detailsData" style="margin-top: 20px;"> + + + <div class="columns medium-12 small-12 margin-top-medium card-3"> + <div class="responsive-table top-space-20"> + <table class="datatable-pdx table-borderedPdx pdx-table head-left"> + <thead> + <tr> + <th colspan="2"> Patient </th> + </tr> + </thead> + <tbody> + + <tr> + <th class="text-left medium-4">Sex</th> + <td th:text="${data.patient.gender}"></td> + </tr> + <tr> + <th class="text-left medium-4">Race / Ethnicity</th> + <td> + <span th:text="${data.race}"></span> + <span th:if="${not ( #strings.isEmpty(data.race) || #strings.isEmpty(data.ethnicity) ) }"> / </span> + <span th:text="${data.ethnicity}"></span> + </td> + </tr> + + <tr> + <th class="text-left medium-4"> Derived Model </th> + <td> + <span th:text="${data.modelId}"> present model</span> + <span th:each="relMod:${data.relatedModels}"> + <a th:text="${relMod}" th:href="@{'/pdx/'+${data.dataSource}+'/'+${relMod}}"></a> + </span> + </td> + </tr> + + + <!--<tr> + <th class="text-left medium-4">Primary Tissue</th> + <td class="text-left" th:text="${data.primaryTissue}"></td> + </tr> + + <tr> + <th class="text-left medium-4">Collection Site</th> + <td class="text-left" th:text="${data.collectionSite}"></td> + </tr> + + <tr> + <th class="text-left medium-4">Tumor Type</th> + <td class="text-left" th:text="${data.tumorType}"></td> + </tr> --> + + </tbody> + </table> + </div> + </div> - <section class="row large-12 medium-12 expanded" id="detailsData" style="margin-top: 20px;"> - <div class="columns medium-12 small-12 margin-top-medium card-3"> - <div class="responsive-table top-space-20"> - <table class="datatable-pdx table-borderedPdx pdx-table head-left"> - <thead> - <tr> - <th colspan="2"> Patient </th> - </tr> - </thead> - <tbody> + <div class="columns medium-12 small-12 margin-top-10 card-3"> + <div class="responsive-table top-space-20"> + <table class="datatable-pdx pdx-table head-left"> + <thead> + <tr> + <th> Patient Tumor Collection For PDX Model </th> + </tr> + </thead> + </table> + <table class="pdx-table head-left top-space-n-20"> + <thead> + <th></th> + <th:block + th:if="${not #lists.isEmpty(data.patient.collectionEvents)}" + th:each="event, iter : ${data.patient.collectionEvents}"> + + <th th:if="${event.pdxMouse != data.modelId}" + th:text="${'Collection '} + ${' (Other Model)'}"> + Collection + </th> + <th th:if="${event.pdxMouse == data.modelId}" + th:text="${'Collection '} + ${' (Current Model)'}"> + Collection + </th> + + </th:block> + </thead> + <tbody> + + <th:block + th:if="${not #lists.isEmpty(data.patient.collectionEvents)}"> <tr> - <th class="text-left medium-4">Sex</th> - <td th:text="${data.patient.gender}"></td> - </tr> - <tr> - <th class="text-left medium-4">Race / Ethnicity</th> - <td> - <span th:text="${data.race}"></span> - <span th:if="${not ( #strings.isEmpty(data.race) || #strings.isEmpty(data.ethnicity) ) }"> / </span> - <span th:text="${data.ethnicity}"></span> - </td> + <th class="text-left medium-4">Age</th> + + <th:block + th:each="event : ${data.patient.collectionEvents}"> + <td th:text="${event.age}" + th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> + ... AGE ... + </td> + </th:block> </tr> <tr> - <th class="text-left medium-4"> Derived Model </th> - <td> - <span th:text="${data.modelId}"> present model</span> - <span th:each="relMod:${data.relatedModels}"> - <a th:text="${relMod}" th:href="@{'/pdx/'+${data.dataSource}+'/'+${relMod}}"></a> - </span> - </td> + <th class="text-left medium-4"> Diagnosis</th> + + <th:block + th:each="event : ${data.patient.collectionEvents}"> + <td th:text="${event.diagnosis}" + th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> + ... DIAGNOSIS ... + </td> + </th:block> </tr> - - <!--<tr> - <th class="text-left medium-4">Primary Tissue</th> - <td class="text-left" th:text="${data.primaryTissue}"></td> + <tr> + <th class="text-left medium-4"> Type</th> + + <th:block th:each="event : ${data.patient.collectionEvents}"> + <td th:text="${event.type}" + th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> + ... TYPE ... + </td> + </th:block> </tr> <tr> - <th class="text-left medium-4">Collection Site</th> - <td class="text-left" th:text="${data.collectionSite}"></td> + <th class="text-left medium0-4"> PDX Mouse</th> + <th:block th:each="event : ${data.patient.collectionEvents}"> + <td th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> + + <span th:if="${#strings.equals(event.pdxMouse, data.modelId) }" + th:text="${event.pdxMouse}"> + ... MODELID ... + </span> + + <span th:if="${not #strings.equals(event.pdxMouse, data.modelId) }"> + <a th:text="${event.pdxMouse}" + th:href="@{'/pdx/'+${data.dataSource}+'/'+${event.pdxMouse}}" + target="_blank"> ... MODELID ... </a> + </span> + </td> + + </th:block> </tr> <tr> - <th class="text-left medium-4">Tumor Type</th> - <td class="text-left" th:text="${data.tumorType}"></td> - </tr> --> - - </tbody> - </table> - </div> - </div> - - + <th class="text-left medium-4">Collection Site</th> - <div class="columns medium-12 small-12 margin-top-10 card-3"> - <div class="responsive-table top-space-20"> - <table class="datatable-pdx pdx-table head-left"> - <thead> - <tr> - <th> Patient Tumor Collection For PDX Model </th> + <th:block + th:each="event : ${data.patient.collectionEvents}"> + <td th:text="${event.collectionSite}" + th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> + ... COLLECTION SITE ... + </td> + </th:block> </tr> - </thead> - </table> - <table class="pdx-table head-left top-space-n-20"> - <thead> - <th></th> - <th:block - th:if="${not #lists.isEmpty(data.patient.collectionEvents)}" - th:each="event, iter : ${data.patient.collectionEvents}"> - - <th th:if="${event.pdxMouse != data.modelId}" - th:text="${'Collection '} + ${' (Other Model)'}"> - Collection - </th> - <th th:if="${event.pdxMouse == data.modelId}" - th:text="${'Collection '} + ${' (Current Model)'}"> - Collection - </th> - - </th:block> - </thead> - <tbody> - - <th:block - th:if="${not #lists.isEmpty(data.patient.collectionEvents)}"> - - <tr> - <th class="text-left medium-4">Age</th> - <th:block - th:each="event : ${data.patient.collectionEvents}"> - <td th:text="${event.age}" - th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> - ... AGE ... - </td> - </th:block> - </tr> - - <tr> - <th class="text-left medium-4"> Diagnosis</th> + </th:block> + + </tbody> + </table> + + <table class="pdx-table head-left"> + <tbody> + <tr> + <th class="text-left medium-4"> Grade</th> + <td th:if="${#strings.equalsIgnoreCase(data.grade, 'Not Specified') || #strings.equalsIgnoreCase(data.gradeClassification, 'Not Specified')}"> + <span th:utext="${data.grade}"></span> + </td> + <td th:if="${not ( #strings.equalsIgnoreCase(data.grade, 'Not Specified') || #strings.equalsIgnoreCase(data.gradeClassification, 'Not Specified') ) }"> + <span th:utext="${data.grade}"></span> + <span th:utext="${'(<b> Classification: </b>'+data.gradeClassification+')'}"></span> + </td> + </tr> + + <tr> + <th class="text-left medium-4"> Stage</th> + <td th:if="${#strings.equalsIgnoreCase(data.stage, 'Not Specified') || #strings.equalsIgnoreCase(data.stageClassification, 'Not Specified')}"> + <span th:utext="${data.stage}"></span> + </td> + <td th:if="${not ( #strings.equalsIgnoreCase(data.stage, 'Not Specified') || #strings.equalsIgnoreCase(data.stageClassification, 'Not Specified') ) }"> + <span th:utext="${data.stage}"></span> + <span th:utext="${'(<b> Classification: </b>'+data.stageClassification+')'}"></span> + </td> + </tr> + </tbody> + </table> - <th:block - th:each="event : ${data.patient.collectionEvents}"> - <td th:text="${event.diagnosis}" - th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> - ... DIAGNOSIS ... - </td> - </th:block> - </tr> - - <tr> - <th class="text-left medium-4"> Type</th> - - <th:block th:each="event : ${data.patient.collectionEvents}"> - <td th:text="${event.type}" - th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> - ... TYPE ... - </td> - </th:block> - </tr> - - <tr> - <th class="text-left medium0-4"> PDX Mouse</th> - <th:block th:each="event : ${data.patient.collectionEvents}"> - <td th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> - - <span th:if="${#strings.equals(event.pdxMouse, data.modelId) }" - th:text="${event.pdxMouse}"> - ... MODELID ... - </span> + </div> + </div> - <span th:if="${not #strings.equals(event.pdxMouse, data.modelId) }"> - <a th:text="${event.pdxMouse}" - th:href="@{'/pdx/'+${data.dataSource}+'/'+${event.pdxMouse}}" - target="_blank"> ... MODELID ... </a> - </span> - </td> - </th:block> - </tr> - <tr> - <th class="text-left medium-4">Collection Site</th> - <th:block - th:each="event : ${data.patient.collectionEvents}"> - <td th:text="${event.collectionSite}" - th:class="${#strings.equals(event.pdxMouse, data.modelId) } ? 'highlight-bg' : 'table-focus' "> - ... COLLECTION SITE ... - </td> - </th:block> - </tr> - </th:block> - </tbody> - </table> + <div class="tabs-content style-2" data-tabs-content="example2-tabs"> + <div class="tabs-panel is-active" id="summary"> - <table class="pdx-table head-left"> - <tbody> - <tr> - <th class="text-left medium-4"> Grade</th> - <td th:if="${#strings.equalsIgnoreCase(data.grade, 'Not Specified') || #strings.equalsIgnoreCase(data.gradeClassification, 'Not Specified')}"> - <span th:utext="${data.grade}"></span> - </td> - <td th:if="${not ( #strings.equalsIgnoreCase(data.grade, 'Not Specified') || #strings.equalsIgnoreCase(data.gradeClassification, 'Not Specified') ) }"> - <span th:utext="${data.grade}"></span> - <span th:utext="${'(<b> Classification: </b>'+data.gradeClassification+')'}"></span> - </td> - </tr> + <div class="row large-12 medium-12 expanded"> - <tr> - <th class="text-left medium-4"> Stage</th> - <td th:if="${#strings.equalsIgnoreCase(data.stage, 'Not Specified') || #strings.equalsIgnoreCase(data.stageClassification, 'Not Specified')}"> - <span th:utext="${data.stage}"></span> - </td> - <td th:if="${not ( #strings.equalsIgnoreCase(data.stage, 'Not Specified') || #strings.equalsIgnoreCase(data.stageClassification, 'Not Specified') ) }"> - <span th:utext="${data.stage}"></span> - <span th:utext="${'(<b> Classification: </b>'+data.stageClassification+')'}"></span> - </td> - </tr> - </tbody> - </table> </div> </div> + </div> + </section> + <!-- Disable Current Treatment Table + <section class="row large-12 medium-12 expanded" + id="detailsData" + style="margin-top: 20px;" + th:if="${ #bools.isTrue(data.patient.currentTreatmentExists) } "> - - + <div class="row large-12 medium-12 expanded"> + <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> + <li class="tabs-title is-active"><a href="#initialDiagnosis" aria-selected="true" style="font-size: 15px; padding: 15px;"> Current Therapy </a></li> + </ul> + </div> <div class="tabs-content style-2" data-tabs-content="example2-tabs"> <div class="tabs-panel is-active" id="summary"> <div class="row large-12 medium-12 expanded"> + <div class="columns medium-12 small-12 margin-top-10 card-3"> + <div class="responsive-table" style="margin-top: 20px;"> + <table class="pdx-table head-left"> + <thead> + <th> Date Regimen Started </th> + <th> Regimen </th> + <th> Dose </th> + <th> Best Response </th> + <th> Duration (Months) </th> + </thead> + <tbody> - </div> - </div> - </div> - </section> - - - <!-- Disable Current Treatment Table - <section class="row large-12 medium-12 expanded" - id="detailsData" - style="margin-top: 20px;" - th:if="${ #bools.isTrue(data.patient.currentTreatmentExists) } "> - - <div class="row large-12 medium-12 expanded"> - <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> - <li class="tabs-title is-active"><a href="#initialDiagnosis" aria-selected="true" style="font-size: 15px; padding: 15px;"> Current Therapy </a></li> - </ul> - </div> - - <div class="tabs-content style-2" data-tabs-content="example2-tabs"> - <div class="tabs-panel is-active" id="summary"> - - <div class="row large-12 medium-12 expanded"> - - <div class="columns medium-12 small-12 margin-top-10 card-3"> - <div class="responsive-table" style="margin-top: 20px;"> - <table class="pdx-table head-left"> - <thead> - <th> Date Regimen Started </th> - <th> Regimen </th> - <th> Dose </th> - <th> Best Response </th> - <th> Duration (Months) </th> - </thead> - <tbody> - - - <th:block th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" - th:each="treatment : ${data.patient.treatmentSummaries}"> - <tr th:if="${ #bools.isTrue(treatment.current) } "> + <th:block th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" + th:each="treatment : ${data.patient.treatmentSummaries}"> - <th class="text-left medium-4" - th:text="${treatment.treatmentDate+' (Current)'}"> ...DATE... </th> + <tr th:if="${ #bools.isTrue(treatment.current) } "> - <td th:text="${treatment.drugNames}"></td> - <td th:text="${treatment.dose}"> </td> + <th class="text-left medium-4" + th:text="${treatment.treatmentDate+' (Current)'}"> ...DATE... </th> + <td th:text="${treatment.drugNames}"></td> + <td th:text="${treatment.dose}"> </td> - <td th:text="${treatment.response}"> </td> - <td th:text="${treatment.duration}"> </td> - </tr> + <td th:text="${treatment.response}"> </td> + <td th:text="${treatment.duration}"> </td> - </th:block> + </tr> - </tbody> - </table> - </div> + </th:block> + </tbody> + </table> </div> + </div> </div> </div> - </section> --> + </div> + </section> --> - <section class="row large-12 medium-12 expanded" - id="detailsData" - style="margin-top: 20px;" - th:if="${ #bools.isTrue(data.patient.treatmentExists) } "> + <section class="row large-12 medium-12 expanded" + id="detailsData" + style="margin-top: 20px;" + th:if="${ #bools.isTrue(data.patient.treatmentExists) } "> - <div class="row large-12 medium-12 expanded"> - <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> - <li class="tabs-title is-active"><a href="#initialDiagnosis" - aria-selected="true" - style="font-size: 15px; padding: 15px;"> - Patient Therapies & Response </a></li> - </ul> - </div> + <div class="row large-12 medium-12 expanded"> + <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> + <li class="tabs-title is-active"><a href="#initialDiagnosis" + aria-selected="true" + style="font-size: 15px; padding: 15px;"> + Patient Therapies & Response </a></li> + </ul> + </div> - <div class="tabs-content style-2" data-tabs-content="example2-tabs"> - <div class="tabs-panel is-active" id="summary"> + <div class="tabs-content style-2" data-tabs-content="example2-tabs"> + <div class="tabs-panel is-active" id="summary"> - <!-- Summary first row --> - <div class="row large-12 medium-12 expanded"> - - <div class="columns medium-12 small-12 margin-top-10 card-3"> - <div class="responsive-table" style="margin-top: 20px;"> - <table class="pdx-table head-left"> - <thead> - <th> Date Regimen Started</th> - <th> Regimen</th> - <th> Dose</th> - <th> Best Response</th> - <th> Duration (Months)</th> - </thead> - <tbody> + <!-- Summary first row --> + <div class="row large-12 medium-12 expanded"> + <div class="columns medium-12 small-12 margin-top-10 card-3"> + <div class="responsive-table" style="margin-top: 20px;"> + <table class="pdx-table head-left"> + <thead> + <th> Date Regimen Started</th> + <th> Regimen</th> + <th> Dose</th> + <th> Best Response</th> + <th> Duration (Months)</th> + </thead> + <tbody> - <th:block - th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" - th:each="treatment : ${data.patient.treatmentSummaries}"> - <tr th:if="${ #bools.isFalse(treatment.current) } "> + <th:block + th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" + th:each="treatment : ${data.patient.treatmentSummaries}"> - <th class="text-left medium-4 capt-text" - th:text="${treatment.treatmentDate}"> ...DATE... - </th> + <tr th:if="${ #bools.isFalse(treatment.current) } "> - <td th:text="${treatment.drugNames}"></td> - <td th:text="${treatment.dose}"></td> - <td th:text="${treatment.response}"></td> - <td th:text="${treatment.duration}"></td> + <th class="text-left medium-4 capt-text" + th:text="${treatment.treatmentDate}"> ...DATE... + </th> - </tr> + <td th:text="${treatment.drugNames}"></td> + <td th:text="${treatment.dose}"></td> + <td th:text="${treatment.response}"></td> + <td th:text="${treatment.duration}"></td> - </th:block> + </tr> + </th:block> - <th:block - th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" - th:each="treatment : ${data.patient.treatmentSummaries}"> - <tr th:if="${ #bools.isTrue(treatment.current) } "> + <th:block + th:if="${not #lists.isEmpty(data.patient.treatmentSummaries)}" + th:each="treatment : ${data.patient.treatmentSummaries}"> - <th class="text-left medium-4" - th:text="${treatment.treatmentDate+' (Current)'}"> - ...DATE... - </th> + <tr th:if="${ #bools.isTrue(treatment.current) } "> - <td th:text="${treatment.drugNames}"></td> - <td th:text="${treatment.dose}"></td> + <th class="text-left medium-4" + th:text="${treatment.treatmentDate+' (Current)'}"> + ...DATE... + </th> + <td th:text="${treatment.drugNames}"></td> + <td th:text="${treatment.dose}"></td> - <td th:text="${treatment.response}"></td> - <td th:text="${treatment.duration}"></td> - </tr> + <td th:text="${treatment.response}"></td> + <td th:text="${treatment.duration}"></td> - </th:block> + </tr> - </tbody> - </table> - </div> + </th:block> + </tbody> + </table> </div> + </div> </div> </div> - </section> + </div> + </section> - </div> + </div> @@ -706,223 +726,227 @@ - <div class="tabs-panel is-active" id="variation"> + <div class="tabs-panel is-active" id="variation"> - <div class="row large-12 medium-12 expanded" id="variationTableSummary"> + <div class="row large-12 medium-12 expanded" id="variationTableSummary"> - <div class="tab hideContent0" role="tabpanel" th:if="${data.molecularDataRows.size() > 0}"> + <div class="tab hideContent0" role="tabpanel" th:if="${data.molecularDataRows.size() > 0}"> - <div th:if="${not #lists.isEmpty(data.molecularDataRows)}" - class="row large-12 medium-12 expanded"> + <div th:if="${not #lists.isEmpty(data.molecularDataRows)}" + class="row large-12 medium-12 expanded"> - <div class="columns medium-12 small-12 margin-top-10 card-3"> - <div class="responsive-table" style="margin-top: 20px;"> + <div class="columns medium-12 small-12 margin-top-10 card-3"> + <div class="responsive-table" style="margin-top: 20px;"> - <table class="datatable-pdx pdx-table table-borderedPdx head-left" data-tabs - id="example-tabs"> - <thead> - <th>Sample ID</th> - <th>Sample Type</th> - <th>Engrafted Tumor Passage</th> - <th>Data Type</th> - <th>Data Available</th> - <th>Platform Used</th> - <th>Raw Data</th> - </thead> - <tbody> + <table class="datatable-pdx pdx-table table-borderedPdx head-left" data-tabs + id="example-tabs"> + <thead> + <th>Sample ID</th> + <th>Sample Type</th> + <th>Engrafted Tumor Passage</th> + <th>Data Type</th> + <th>Data Available</th> + <th>Platform Used</th> + <th>Raw Data</th> + </thead> + <tbody> - <tr th:each="dataRow,iter : ${data.molecularDataRows}" - class="tabs-title" style="float:none; text-transform: capitalize;" - th:classappend="( ${iter.index} == 0 ) ? 'is-active' : '' "> - - <td th:text="${dataRow.sampleId}"> ...</td> - <td th:text="${dataRow.sampleType}"> ...</td> - <td th:text="${'Passage '+dataRow.engraftedTumorPassage}"> ...</td> - <td th:text="${dataRow.molcharType}"> ...</td> - - <td> - <span th:if="${dataRow.isVisible == 'YES' and dataRow.dataAssociated != 'YES'}" th:text="'Data is not available in the Finder'"></span> - <a th:if="${dataRow.dataAssociated == 'YES' or dataRow.isVisible == 'NO'}" class="molecularDataLink" - style="color: #06369d; text-decoration: none;" - data-th-attr="data-tabs-target=${dataRow.dataAvailableLabel}, aria-selected=( ${iter.index} == 0 ) ? 'true' : '' " - th:title="${dataRow.sampleId+' | '+data.mappedOntologyTermLabel+' | '+dataRow.sampleType+' | '+dataRow.engraftedTumorPassage+' | '+dataRow.platformUsedLabel}" - th:text="'View data'" - th:id="${'mc___'+dataRow.molcharId}"> - TAB TITLES - </a> - </td> - <td> - <a th:if="${dataRow.platformUsedUrl != null or dataRow.platformUsedLabel == ''}" target="_blank" - style="color: #06369d; text-decoration: none;" - th:text="${#strings.replace(dataRow.platformUsedLabel,'_',' ')}" - th:onclick="'window.open(\''+${dataRow.platformUsedUrl}+'\')'"> - ... - </a> - <span th:if="${dataRow.platformUsedUrl == null}" th:text="${dataRow.platformUsedLabel}"></span> - </td> - <td> - <a th:text="${dataRow.rawDataLabel}" - style="color: #06369d; text-decoration: none;" - th:onclick="'window.open(\' '+${dataRow.rawDataLink}+'\')'"> - ... - </a> - <span th:if="${dataRow.rawDataLink == ''} " th:text="'Not Available'" ></span> - </td> - </tr> + <tr th:each="dataRow,iter : ${data.molecularDataRows}" + class="tabs-title" style="float:none; text-transform: capitalize;" + th:classappend="( ${iter.index} == 0 ) ? 'is-active' : '' "> - </tbody> - </table> + <td th:text="${dataRow.sampleId}"> ...</td> + <td th:text="${dataRow.sampleType}"> ...</td> + <td th:text="${'Passage '+dataRow.engraftedTumorPassage}"> ...</td> + <td th:text="${dataRow.molcharType}"> ...</td> + + <td> + <span th:if="${dataRow.isVisible == 'YES' and dataRow.dataAssociated != 'YES'}" th:text="'Data is not available in the Finder'"></span> + <a th:if="${dataRow.dataAssociated == 'YES' or dataRow.isVisible == 'NO'}" class="molecularDataLink" + style="color: #06369d; text-decoration: none;" + data-th-attr="data-tabs-target=${dataRow.dataAvailableLabel}, aria-selected=( ${iter.index} == 0 ) ? 'true' : '' " + th:title="${dataRow.sampleId+' | '+data.mappedOntologyTermLabel+' | '+dataRow.sampleType+' | '+dataRow.engraftedTumorPassage+' | '+dataRow.platformUsedLabel}" + th:text="'View data'" + th:id="${'mc___'+dataRow.molcharId}"> + TAB TITLES + </a> + </td> + <td> + <a th:if="${dataRow.platformUsedUrl != null or dataRow.platformUsedLabel == ''}" target="_blank" + style="color: #06369d; text-decoration: none;" + th:text="${#strings.replace(dataRow.platformUsedLabel,'_',' ')}" + th:data-platformurl="${dataRow.platformUsedUrl}" - </div> - </div> + onclick="openNewWindow(this.getAttribute('data-platformurl'));"> + ... + </a> + <span th:if="${dataRow.platformUsedUrl == null}" th:text="${dataRow.platformUsedLabel}"></span> + </td> + <td> + <a th:text="${dataRow.rawDataLabel}" + style="color: #06369d; text-decoration: none;" + th:attr="onclick=|window.open('${dataRow.rawDataLink}')|"> + ... + </a> + <span th:if="${dataRow.rawDataLink == ''} " th:text="'Not Available'" ></span> + </td> + </tr> + + </tbody> + </table> + + </div> </div> </div> </div> + </div> - <div id="omicDataContainer"> - <div class="row large-12 medium-12 expanded top-space-30 "> - <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> - <li class="tabs-title is-active"> - <a href="#initialDiagnosis" - aria-selected="true" - style="font-size: 15px; padding: 15px;"> - Genomic Data (<span id="omicDataCount"></span>) <!-- data.variationDataCount --> - </a> - </li> - </ul> - </div> + <div id="omicDataContainer"> + <div class="row large-12 medium-12 expanded top-space-30 "> + <ul class="tabs style-2" data-deep-link="true" data-tabs id="example2-tabs"> + <li class="tabs-title is-active"> + <a href="#initialDiagnosis" + aria-selected="true" + style="font-size: 15px; padding: 15px;"> + Genomic Data (<span id="omicDataCount"></span>) <!-- data.variationDataCount --> + </a> + </li> + </ul> + </div> - <div class="columns medium-12 small-12 card-3" style="padding: 15px;"> - <div class="columns medium-6 small-12" id="download-data" style="float: right; margin-top:-65px; margin-right:-30px;"> - <div class="columns medium-5 small-12 text-right" style="padding: 0px;"> - <label class="dropdown"> - <a class="button outline secondary"> - Download Results <i class="icon icon-functional" data-icon="="></i> - </a> - <input type="checkbox" class="dd-input" id="test"> - - <ul class="dd-menu"> - <th:block th:each="dataRow,iter : ${data.molecularDataRows}"> - <li th:if="${dataRow.isVisible == 'YES' and dataRow.dataAssociated == 'YES'}"> - <a th:href="@{'/pdx/'+${data.dataSource}+'/'+${data.modelId}+'/'+${#strings.replace(dataRow.molcharType,' ','-')}+'/'+${dataRow.molcharId}+'/export'}" - th:text="${#strings.capitalizeWords(dataRow.molcharType)}"> Download ... </a> - </li> - </th:block> - <li class="divider"></li> - <!--<li> - <a target="_blank" - style="color: #06369d; text-decoration: none;" - th:onclick=" 'window.open(\''+${'https://pdmr.cancer.gov/content/docs/NCI_Cancer_Gene_Panel.pdf'}+'\')' "> Download All </a> - </li> - <li> - <a target="_blank"> Downlload All </a> - </li>--> - </ul> - </label> - </div> + <div class="columns medium-12 small-12 card-3" style="padding: 15px;"> + <div class="columns medium-6 small-12" id="download-data" style="float: right; margin-top:-65px; margin-right:-30px;"> + <div class="columns medium-5 small-12 text-right" style="padding: 0px;"> + <label class="dropdown" style="margin-top: 10px;"> + <a class="button outline secondary"> + Download Results <i class="icon icon-functional" data-icon="="></i> + </a> + <input type="checkbox" class="dd-input" id="test"> + <ul class="dd-menu"> + <th:block th:each="dataRow,iter : ${data.molecularDataRows}"> + <li th:if="${dataRow.isVisible == 'YES' and dataRow.dataAssociated == 'YES'}"> + <a th:href="@{'/pdx/'+${data.dataSource}+'/'+${data.modelId}+'/'+${#strings.replace(dataRow.molcharType,' ','-')}+'/'+${dataRow.molcharId}+'/export'}" + th:text="${#strings.capitalizeWords(dataRow.molcharType)}"> Download ... </a> + </li> + </th:block> + + <li class="divider"></li> + <!--<li> + <a target="_blank" + style="color: #06369d; text-decoration: none;" + th:onclick=" 'window.open(\''+${'https://pdmr.cancer.gov/content/docs/NCI_Cancer_Gene_Panel.pdf'}+'\')' "> Download All </a> + </li> + <li> + <a target="_blank"> Downlload All </a> + </li>--> + </ul> + </label> + </div> - <div id="customSearch" class="columns medium-7 small-12 text-right" style="padding: 0px;"> - <!-- Datatable Search Box --> - </div> + <div id="customSearch" class="columns medium-7 small-12 text-right" style="padding:0px; margin-top:10px"> + <!-- Datatable Search Box --> </div> - <div class="tabs-content" data-tabs-content="example-tabs"> + </div> - <div class="tabs-panel is-active" - style="border-top: 1px solid #5ea88f; margin-top:20px;"> + <div class="tabs-content" data-tabs-content="example-tabs"> - <hr id="hrTitle" class="hr-text" data-content="THE PLATFORM"> + <div class="tabs-panel is-active" + style="border-top: 1px solid #5ea88f; margin-top:20px;"> - <div class="table-responsive"> + <hr id="hrTitle" class="hr-text" data-content="THE PLATFORM"> - <h4 class="bLine" th:classappend="( true ) ? '' : 'topSpace50' "> + <div class="table-responsive"> - <span class="hdc">Sample ID: </span> - <b class="black" id="clickedSampleId"></b> <!-- data.techNPassToSampleId['__${technology.key}__'+'__${technology.value[num-1]}__'] --> + <h4 class="bLine" th:classappend="( true ) ? '' : 'topSpace50' "> - <span class="hdc">Histology:</span> - <b class="black" id="modelHistology"></b> <!-- strings.capitalize(data.diagnosis) --> + <span class="hdc">Sample ID: </span> + <b class="black" id="clickedSampleId"></b> <!-- data.techNPassToSampleId['__${technology.key}__'+'__${technology.value[num-1]}__'] --> - <span class="hdc">Tumor Type: </span> - <b class="black" id="clickedTumorType">Engrafted Tumor</b> + <span class="hdc">Histology:</span> + <b class="black" id="modelHistology"></b> <!-- strings.capitalize(data.diagnosis) --> - <span class="hdc">Passage: </span> - <b class="black" id="clickedPassage"></b> + <span class="hdc">Tumor Type: </span> + <b class="black" id="clickedTumorType">Engrafted Tumor</b> - <span class="hdc">Platform: </span> - <b class="black" id="clickedTech"></b> + <span class="hdc">Passage: </span> + <b class="black" id="clickedPassage"></b> - </h4> + <span class="hdc">Platform: </span> + <b class="black" id="clickedTech"></b> - <div style="text-align: center;"> <img th:src="@{/images/loading2.gif}" id="preLoader"/> </div> - <div class="responsive-table" style="margin-top: 20px;" id="variationTableData"> + </h4> - </div> - </div> + <div style="text-align: center;"> <img th:src="@{/images/loading2.gif}" id="preLoader"/> </div> + <div class="responsive-table" style="margin-top: 20px;" id="variationTableData"> + </div> </div> + </div> </div> </div> </div> + </div> - <div class="tabs-panel" id="dosing_studies"> - <div th:if="${not #lists.isEmpty(data.dosingStudy)}"> + <div class="tabs-panel" id="dosing_studies"> + <div th:if="${not #lists.isEmpty(data.dosingStudy)}"> - <div class="columns medium-12 small-12 margin-top-10 card-3"> - <div class="responsive-table" style="margin-top: 20px;"> + <div class="columns medium-12 small-12 margin-top-10 card-3"> + <div class="responsive-table" style="margin-top: 20px;"> - <div th:if="${data.dosingStudyProtocolUrl} != null" class="drug_spacing"> - <a th:href="${data.dosingStudyProtocolUrl}">Dosing study protocol</a> - </div> + <div th:if="${data.dosingStudyProtocolUrl} != null" class="drug_spacing"> + <a th:href="${data.dosingStudyProtocolUrl}">Dosing study protocol</a> + </div> - <table class="datatable-pdx pdx-table table-borderedPdx head-left"> - <thead> - <th>Drug</th> - <th>Dose</th> - <th>Response</th> - </thead> - <tbody> - <tr th:each="drugData, iter : ${data.dosingStudy}"> - <td th:text="${drugData.drugName}"></td> - <td th:text="${drugData.dose}"></td> - <td th:text="${drugData.response}"></td> - </tr> - </tbody> - </table> + <table class="datatable-pdx pdx-table table-borderedPdx head-left"> + <thead> + <th>Drug</th> + <th>Dose</th> + <th>Response</th> + </thead> + <tbody> + <tr th:each="drugData, iter : ${data.dosingStudy}"> + <td th:text="${drugData.drugName}"></td> + <td th:text="${drugData.dose}"></td> + <td th:text="${drugData.response}"></td> + </tr> + </tbody> + </table> - </div> </div> - </div> - <div th:if="${#lists.isEmpty(data.dosingStudy)}"></div> </div> + + <div th:if="${#lists.isEmpty(data.dosingStudy)}"></div> </div> - </section> - </div> + + </div> + </section> </section> - <th:block th:include="fragments/shared :: footer"></th:block> </div> -</div> + <!-- End suggested layout containers / #content --> + <th:block th:include="fragments/shared :: footer"></th:block> +</div> <!-- JavaScript --> -<!--<script type='text/javascript' th:src="@{/js/banner-gdpr.js}"></script>--> +<script type='text/javascript' th:src="@{/js/banner-gdpr.js}"></script> <div id="data-protection-message-configuration" data-message="Your message and links here." data-service-id="ebi" data-data-protection-version="0.1"> @@ -1023,22 +1047,6 @@ } </script> -<div class="box-fixed-notice box-fixed-notice--old-browsers"> - <div class="row-main"> - <form action="/" enctype="multipart/form-data" method="post"> <p class="box-fixed-notice__text"> - You are running an old browser version. We recommend updating your browser to its latest version. - </p> - <p class="box-fixed-notice__btn-wrap"> - <a href="/system/your-browser-is-outdated" class="btn btn-white btn-border btn-s"> - <span>More info</span> - </a> - <button type="submit" class="btn btn-white btn-border btn-s"> - <span>Close</span> - </button> - </p> - <input name='ufprt' type='hidden' value='lKFncnBaM6PLAWMCyZ6uii0CCveb66W1RDWg3qMNy4WCgWWvBUWX1xJjY62evDRYEvPmouUm6zn6TTNReIzqLBuw7ZXh09ufNDig51U+nuLBvlTuVpmvzfLBQaY+R7XhPg5CzowZxUYkfEmfuMPqRC7GgftaUBX/RKCir0bkaHRpD7bz' /></form> </div> -</div> - <script type="text/javascript"> window.trackDownloads = true; diff --git a/web/src/main/resources/templates/fragments/filter-components.html b/web/src/main/resources/templates/fragments/filter-components.html index 41c77efec95790249ac739f7d1f89e99a1236277..ef73836d5318ac18303482688095a64a12f48575 100644 --- a/web/src/main/resources/templates/fragments/filter-components.html +++ b/web/src/main/resources/templates/fragments/filter-components.html @@ -18,7 +18,7 @@ <div class="row topSace10"> <div class="columns nospace small-12 large-6"> <input type="text" class="auto-suggest-field-2" - th:onblur="|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+'0'}','${filterComponent.options2}')|" + th:attr="onblur=|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+'0'}','${filterComponent.options2}')|" th:id="${filterComponent.urlParam}+'_'+${#strings.toLowerCase(filterComponent.param1Name)+'0'}"/> </div> @@ -119,13 +119,13 @@ <button th:unless="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> OR </button> <button th:if="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#maps.size(filterComponent.selected)}')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#maps.size(filterComponent.selected)}')|"> OR </button> </div> @@ -151,7 +151,7 @@ <div class="row topSace10"> <div class="columns nospace small-12 large-6"> <input type="text" class="auto-suggest-field-2" - th:onblur="|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+'0'}','')|" + th:attr="onblur=|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+'0'}','')|" th:id="${filterComponent.urlParam}+'_'+${#strings.toLowerCase(filterComponent.param1Name)+'0'}"/> </div> @@ -168,7 +168,7 @@ style="display:none"> <div class="columns nospace small-12 large-6"> <input type="text" class="auto-suggest-field-2" - th:onblur="|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+i}','')|" + th:attr="onblur=|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+i}','')|" th:id="${filterComponent.urlParam}+'_'+${#strings.toLowerCase(filterComponent.param1Name)}+${i}"/> </div> @@ -189,7 +189,7 @@ <div class="columns nospace small-12 large-6"> <input th:value="${activeComponent.key}" type="text" class="auto-suggest-field-2" - th:onblur="|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+iter.index}','')|" + th:attr="onblur=|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+iter.index}','')|" th:id="${filterComponent.urlParam}+'_'+${#strings.toLowerCase(filterComponent.param1Name)}+${iter.index}"/> </div> @@ -216,7 +216,7 @@ <div class="columns nospace small-12 large-6"> <input type="text" class="auto-suggest-field-2" - th:onblur="|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+i}','')|" + th:attr="onblur=|selectAllOptionsInMyComponent2(this,'${filterComponent.type}','${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param2Name)+i}','')|" th:id="${filterComponent.urlParam}+'_'+${#strings.toLowerCase(filterComponent.param1Name)}+${i}"/> </div> @@ -239,13 +239,13 @@ <button th:unless="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> OR </button> <button th:if="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#maps.size(filterComponent.selected)}')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#maps.size(filterComponent.selected)}')|"> OR </button> </div> @@ -326,13 +326,13 @@ <button th:unless="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','1')|"> OR </button> <button th:if="${filterComponent.active}" href="#" class="icoButn columns large-2 ORButton" - th:onclick="|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#lists.size(filterComponent.selected)}')|"> + th:attr="onclick=|displayMore('${filterComponent.urlParam+ '_'+ #strings.toLowerCase(filterComponent.param1Name)}','${#lists.size(filterComponent.selected)}')|"> OR </button> </div> diff --git a/web/src/main/resources/templates/fragments/shared.html b/web/src/main/resources/templates/fragments/shared.html index 170b40cd9ac05835cfa08abe67b1f698cb858b80..fceb7a6322e0c0c5fe6f236e9a34a95fd63cc5ec 100644 --- a/web/src/main/resources/templates/fragments/shared.html +++ b/web/src/main/resources/templates/fragments/shared.html @@ -523,3 +523,4 @@ </body> </html> + diff --git a/web/src/main/resources/templates/search.html b/web/src/main/resources/templates/search.html index 1f0737a0cc169e2c1263dbea83fd9c40c6e89c10..7d81907241025dd98b8d8a284b95867de914b5d3 100644 --- a/web/src/main/resources/templates/search.html +++ b/web/src/main/resources/templates/search.html @@ -15,14 +15,13 @@ <link rel="icon" th:href="@{/images/favicons/favicon.png}" /> - <script th:src="@{/js/muniweb.aa00301a32be6fbdf120.js}" type="text/javascript"></script> - - + <script th:src="@{/js/muniweb.aa00301a32be6fbdf120.js}" type="text/javascript"></script> + <meta name="apple-mobile-web-app-title" content="EurOPDX Data Portal"> <meta name="application-name" content="EurOPDX Data Portal"> <meta name="msapplication-config" content="https://ebiwd.github.io/pdx-visual-framework/images/favicons/browserconfig.xml?v=1"> - <meta name="theme-color" content="#0032a0"> + <meta name="theme-color" content="#0032a0"> <!-- Add information on the life cycle of this page --> <meta name="ebi:owner" content="PDX"/> <!-- Who should be contacted about changes --> @@ -31,10 +30,10 @@ <meta name="ebi:expiry" content="2018-01-20"/> <!-- When this content is no longer relevant --> <link rel="stylesheet" href="https://dev.ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.2/fonts.css" - type="text/css" media="all"/> - + type="text/css" media="all"/> + <!-- Import Choice Library stylesheet--> <link rel="stylesheet" - href="https://ebi.emblstatic.net/web_guidelines/EBI-Framework/v1.2/libraries/Choices/assets/styles/css/choices.min.css"> + href="https://ebi.emblstatic.net/web_guidelines/EBI-Framework/v1.2/libraries/Choices/assets/styles/css/choices.min.css"> <link rel="stylesheet" th:href="@{/css/app.css}" type="text/css" media="all"/> <link rel="stylesheet" th:href="@{/css/multiple-select.css}"> @@ -64,8 +63,8 @@ <link rel="stylesheet" th:href="@{/css/modifications.css}" /> <link rel="stylesheet" th:href="@{/css/loader.css}"/> <link rel="stylesheet" th:href="@{/css/style.0373a0d584ab4678ef5f.css}" type="text/css"/> - - <script type="text/javascript"> + + <script type="text/javascript"> // show loader after click to export button function btnExport(facetString) { document.getElementById('search-btn-export-btn').onclick = null; @@ -73,8 +72,8 @@ document.getElementById('search-btn-export-loader').style.display = "block"; window.location.href = '/data' + facetString; } - </script> - + </script> + </head> <body class="level2"> @@ -84,7 +83,7 @@ <div id="skip-to"> <a href="#content">Skip to main content</a> </div> - + <th:block th:include="fragments/shared :: header"></th:block> <div id="content"> @@ -93,14 +92,17 @@ <!-- Suggested layout containers --> <section id="main-content-area" role="main"> - - <th:block th:include="fragments/shared :: breadcrumb-search"></th:block> - - - - - - + + <th:block th:include="fragments/shared :: breadcrumb-search"></th:block> + + + + + + + + + <!-- Search FORM Section --> <section> @@ -133,8 +135,8 @@ </select> <span class="form-error margin-top-small"> - You need to enter a search query. - </span> + You need to enter a search query. + </span> </div> <div class="columns small-1 medium-push-2 small-push-3 margin-bottom-none "> <input id="search_submit" @@ -155,18 +157,18 @@ </section> - - - - - - - - - - - - + + + + + + + + + + + + <!-- Search Result and Filter Section --> @@ -392,19 +394,19 @@ </div> </td> + <td data-title="GENE EXPRESSION" th:if="${#lists.contains(websearch.additionalResultTableHeaders, 'GENE EXPRESSION')}"> + <th:block th:each="dData : ${model.geneExpression}"> + <a th:href="@{'/pdx/'+${model.datasource}+'/'+${model.externalId}+'#variation' }" + class="size12" th:utext="${dData} + '<br />'">dData</a> + </th:block> + </td> - - - - - - - - - - - - + <td data-title="CYTOGENETICS" th:if="${#lists.contains(websearch.additionalResultTableHeaders, 'CYTOGENETICS')}"> + <th:block th:each="dData : ${model.cytogenetics}"> + <a th:href="@{'/pdx/'+${model.datasource}+'/'+${model.externalId}+'#variation' }" + class="size12" th:utext="${dData} + '<br />'">dData</a> + </th:block> + </td> </tr> @@ -432,7 +434,7 @@ <li class="pagination-next" th:classappend="${#strings.equals(websearch.page, #strings.toString(websearch.numPages))} ? 'disabled' "> - <span th:if="${#strings.equals(websearch.page, #strings.toString(websearch.numPages))}" + <span th:if="${#strings.equals(websearch.page, #strings.toString(websearch.numPages))}" aria-label="Last page">Last </span> <a th:unless="${#strings.equals(websearch.page, #strings.toString(websearch.numPages))}" th:href="'?' + ${websearch.facetString} + '&page=' + ${websearch.numPages}" @@ -459,13 +461,13 @@ </div> <div class="columns medium-7"> - <button class="button outline secondary" - id="search-btn-export-btn" - th:onclick="'btnExport(\'/search/cbio2?' + ${websearch.facetString} + '\')'"> + <a class="button outline secondary" id="search-btn-export-btn" + th:href="@{'/search/cbio2' + '?' + ${websearch.facetString}}"> <span id="search-btn-export-label">Export to cBioPortal</span> <div class="loader-button-bw" id="search-btn-export-loader"></div> - </button> - </div> + </a> + + </div> </div> @@ -484,7 +486,7 @@ </div> - +</div> <!--<script type='text/javascript' th:src="@{/js/banner-gdpr.js}"></script>--> @@ -505,8 +507,8 @@ <script type="text/javascript" language="javascript" th:inline="javascript"> - // fix selected value in dropdown menu - // document.getElementById("search-items-count-dropdown").value = '?'+[[${websearch.facetString}]] + '&size='+[[${websearch.size}]]; + + var webFacetSections = [[${websearch.webFacetsContainer.webFacetSections}]]; var searchOptions = [[${websearch.mainSearchFieldOptions}]]; @@ -532,9 +534,7 @@ removeItemButton: true, // placeholder: false, // placeholderValue: 'This is a placeholder', - shouldSort: false, - shouldSortItems: false, - maxItemCount: -1, // -1 = infinity + maxItemCount: 1, searchFloor: 0, searchResultLimit: 10, noResultsText: 'No results found', @@ -548,6 +548,8 @@ }); + + function conditionallyShowDropdown(str) { if (str.length < 1) { mainSearch.hideDropdown(); @@ -688,4 +690,4 @@ <script>App.run({});</script> </body> -</html> \ No newline at end of file +</html> diff --git a/web/src/test/java/org/pdxfinder/web/AjaxControllerTest.java b/web/src/test/java/org/pdxfinder/web/AjaxControllerTest.java index 2231e951362b420b2588b2075f99273908f2eda7..92df285483de58a08179089fcab595da0c54d80e 100644 --- a/web/src/test/java/org/pdxfinder/web/AjaxControllerTest.java +++ b/web/src/test/java/org/pdxfinder/web/AjaxControllerTest.java @@ -2,31 +2,24 @@ package org.pdxfinder.web; import static org.hamcrest.Matchers.*; -import org.apache.http.entity.ContentType; -import org.hamcrest.Matchers; + import org.junit.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import static org.mockito.BDDMockito.given; - /* * Created by abayomi on 03/07/2019. */ @@ -54,7 +47,7 @@ public class AjaxControllerTest extends BaseTests { public void getMolecularDataStatAPIOK() throws Exception { String urlTemplate = "/statistics/molecular-data"; this.mockMvc.perform(get(urlTemplate)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.title").exists()) .andExpect(jsonPath("$.title.text", is(""))) .andExpect(jsonPath("$.xAxis").exists()) @@ -78,7 +71,7 @@ public class AjaxControllerTest extends BaseTests { public void getTreatmentStatAPIOK() throws Exception { String urlTemplate = "/statistics/patient-treatment/patients"; this.mockMvc.perform(get(urlTemplate)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.title").exists()) .andExpect(jsonPath("$.title.text").value("PDX Models Treatment Data")) .andExpect(jsonPath("$.xAxis").exists()) diff --git a/web/src/test/java/org/pdxfinder/web/IndexControllerTest.java b/web/src/test/java/org/pdxfinder/web/IndexControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f1c247c2aa84ebcff0a3da81244ef61df2d564bf --- /dev/null +++ b/web/src/test/java/org/pdxfinder/web/IndexControllerTest.java @@ -0,0 +1,38 @@ +package org.pdxfinder.web; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +public class IndexControllerTest extends BaseTests { + + @Autowired + private WebApplicationContext webApplicationContext; + + private MockMvc mockMvc; + + + @Before + public void setup() { + mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); + } + + @Test + public void Given_ContextPath_When_ContextPathRootVisited_Then_RedirectToSearch(){ + try { + this.mockMvc.perform(get("/")) + .andExpect(redirectedUrl("/search")); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + +}