diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..118f32b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: +- package-ecosystem: gradle + directory: "/" + schedule: + interval: daily + time: "18:45" + timezone: "Europe/Rome" + open-pull-requests-limit: 10 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3e8ce0d..6405921 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,86 @@ +################# +# Jetbrains IDEs +################# + + +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + ################# ## Eclipse ################# @@ -70,14 +153,12 @@ build/ *.tlb *.tli *.tlh -*.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb -*.log *.scc # Visual C++ cache files @@ -196,7 +277,6 @@ $RECYCLE.BIN/ *.egg *.egg-info dist/ -build/ eggs/ parts/ var/ @@ -216,3 +296,53 @@ pip-log.txt #Mr Developer .mr.developer.cfg + +############# +## Other exclusions from gitignore.io +############# + +# Created by http://gitignore.io + +### Linux ### +.* +!.gitignore +!.git* + +### OSX ### +.AppleDouble +.LSOverride +Icon + + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +### Java ### +*.class + +# Package Files # +*.jar +*.war +*.ear + +### Gradle ### +# Exclude Folder List # +.gradle/ + +### Eclipse ### +bin/** +tmp/** +tmp/**/* + +### IntelliJ ### +*.iml +*.ipr + +### SVN ### +.svn/ + +/bin diff --git a/Dockerfile b/Dockerfile index c420f20..a213e41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,12 @@ -FROM maven:3-jdk-8 AS builder +FROM openjdk:11-jdk-slim as builder WORKDIR /app COPY . /app -RUN mvn compile war:war +RUN ./gradlew clean build -FROM tomcat:7 -LABEL maintainer=adrian.gschwend@zazuko.com -ENV CATALINA_OPTS="-XX:+UseSerialGC" -COPY --from=builder /app/target/lodview.war /usr/local/tomcat/webapps/lodview.war -CMD ["catalina.sh", "run"] +# Execute container as user. +FROM openjdk:11-jdk-slim +LABEL maintainer=g.nespolino@gmail.com +USER 1001 +COPY --from=builder /app/build/libs/lodview.war /lodview.war +CMD ["java", "-jar", "/lodview.war"] EXPOSE 8080 8009 diff --git a/WebContent/META-INF/MANIFEST.MF b/WebContent/META-INF/MANIFEST.MF deleted file mode 100644 index 254272e..0000000 --- a/WebContent/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Class-Path: - diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..009fde3 --- /dev/null +++ b/build.gradle @@ -0,0 +1,100 @@ +plugins { + id 'org.springframework.boot' version '2.7.5' + id 'io.spring.dependency-management' version '1.1.0' + id 'java' + id "org.owasp.dependencycheck" version "7.3.0" + id 'com.github.spotbugs' version '5.0.13' + id 'war' +} + +group = 'it.gov.innovazione' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + +repositories { + mavenCentral() +} + +dependencies { + implementation('org.springframework.boot:spring-boot-starter-web') { + exclude group: 'org.yaml' + } + + providedRuntime('org.springframework.boot:spring-boot-starter-tomcat') + + implementation 'org.apache.jena:apache-jena-libs:4.6.1' + constraints { + implementation ('com.google.protobuf:protobuf-java:3.21.8') { + because 'previous versions have security bugs' + } + } + + implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' + implementation 'org.apache.commons:commons-text:1.10.0' + + implementation 'org.apache.taglibs:taglibs-standard-spec:1.2.5' + implementation 'org.apache.taglibs:taglibs-standard-impl:1.2.5' + implementation 'org.apache.taglibs:taglibs-standard-jstlel:1.2.5' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' + annotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +spotbugsMain { + excludeFilter = file("${rootProject.projectDir}/config/spotbugs/exclude-filter.xml") + + reports { + html { + enabled = true + destination = file("$buildDir/reports/spotbugs/main/spotbugs.html") + } + } +} + +spotbugsTest { + excludeFilter = file("${rootProject.projectDir}/config/spotbugs/exclude-filter.xml") + reports { + html { + enabled = true + destination = file("$buildDir/reports/spotbugs/test/spotbugs.html") + } + } +} + +dependencyCheck { + skipConfigurations = ['spotbugs'] + +//set up a quality gate for vulnerabilities with high severity level: +//let's consider that a vulnerability has a high severity level if its CVSS score is higher than 7 +//the build is going to fail if vulnerabilities with high severity level found + failBuildOnCVSS = 7 + +//specify a list of known issues which contain: +//false-positives +//confirmed vulnerabilities which are not fixed yet, but we have a ticket for that + suppressionFile = 'config/dependency-check/dependency-check-known-issues.xml' +} + +gradle.taskGraph.whenReady { graph -> + if (graph.hasTask(build)) { + spotbugsMain.enabled = false + dependencyCheckAnalyze.enabled = false + spotbugsTest.enabled = false + } +} + +bootWar { + enabled = true + archiveName("lodview.war") +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000..9540e2b --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/dependency-check/dependency-check-known-issues.xml b/config/dependency-check/dependency-check-known-issues.xml new file mode 100644 index 0000000..6d31793 --- /dev/null +++ b/config/dependency-check/dependency-check-known-issues.xml @@ -0,0 +1,9 @@ + + + + + CVE-2016-1000027 + + diff --git a/config/hooks/copy-precommit-hooks.sh b/config/hooks/copy-precommit-hooks.sh new file mode 100755 index 0000000..5975c3a --- /dev/null +++ b/config/hooks/copy-precommit-hooks.sh @@ -0,0 +1,17 @@ +#!/bin/bash +echo "Copies pre-commit hooks from config/hooks to .git folder" +file='.git/hooks/pre-commit' + +if [ ! -f "$file" ] +then + echo 'No hooks available. Setting up the hook now..' + echo 'Copying pre-commits hook to your git hooks' + cp config/hooks/pre-commit .git/hooks + chmod +x .git/hooks/pre-commit + echo 'Copying Talisman bin to your git hooks' + mkdir -p .git/hooks/bin + cp config/talisman/talisman .git/hooks/bin/ + +else + echo 'A pre-commit hook already exists. Ensure Talisman check and gradle checks are also part of your pre-commit hook' +fi \ No newline at end of file diff --git a/config/hooks/pre-commit b/config/hooks/pre-commit new file mode 100644 index 0000000..c0bb3a8 --- /dev/null +++ b/config/hooks/pre-commit @@ -0,0 +1,3 @@ +#!/bin/bash +.git/hooks/bin/talisman --githook pre-commit +./gradlew checkstyleMain checkstyleTest spotbugsMain spotbugsTest diff --git a/config/spotbugs/exclude-filter.xml b/config/spotbugs/exclude-filter.xml new file mode 100644 index 0000000..5b9bdc4 --- /dev/null +++ b/config/spotbugs/exclude-filter.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/talisman/talisman b/config/talisman/talisman new file mode 100755 index 0000000..f4dd913 Binary files /dev/null and b/config/talisman/talisman differ diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..f286bd1 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,20 @@ +# +# Docker compose to kickstart a development environment +# based on docker. +# +# Start the environment +# +# $ docker-compose up -d dev +# $ docker attach -ti dati-semantic-lodview_dev_1 +# +version: '3.9' +services: + dev: + image: openjdk:11-jdk-slim + volumes: + - .:/code:z + working_dir: /code + entrypoint: + - /usr/bin/tail + - -f + - /dev/null diff --git a/dockerfile-security.rego b/dockerfile-security.rego new file mode 100644 index 0000000..a125164 --- /dev/null +++ b/dockerfile-security.rego @@ -0,0 +1,92 @@ +package main + +# Do Not store secrets in ENV variables +secrets_env = [ + "passwd", + "password", + "pass", + "secret", + "key", + "access", + "api_key", + "apikey", + "token", + "tkn" +] + +deny[msg] { + input[i].Cmd == "env" + val := input[i].Value + contains(lower(val[_]), secrets_env[_]) + msg = sprintf("Line %d: Potential secret in ENV key found: %s", [i, val]) +} + +# Only use trusted base images +deny_untrusted_base_image[msg] { + input[i].Cmd == "from" + val := split(input[i].Value[0], "/") + count(val) > 1 + msg = sprintf("Line %d: use a trusted base image", [i]) +} + +# Do not use 'latest' tag for base imagedeny[msg] { +deny[msg] { + input[i].Cmd == "from" + val := split(input[i].Value[0], ":") + contains(lower(val[1]), "latest") + msg = sprintf("Line %d: do not use 'latest' tag for base images", [i]) +} + +# Avoid curl bashing +deny[msg] { + input[i].Cmd == "run" + val := concat(" ", input[i].Value) + matches := regex.find_n("(curl|wget)[^|^>]*[|>]", lower(val), -1) + count(matches) > 0 + msg = sprintf("Line %d: Avoid curl bashing", [i]) +} + +# Do not upgrade your system packages +upgrade_commands = [ + "apk upgrade", + "apt-get upgrade", + "dist-upgrade", +] + +deny[msg] { + input[i].Cmd == "run" + val := concat(" ", input[i].Value) + contains(val, upgrade_commands[_]) + msg = sprintf("Line: %d: Do not upgrade your system packages", [i]) +} + +# Do not use ADD if possible +deny[msg] { + input[i].Cmd == "add" + msg = sprintf("Line %d: Use COPY instead of ADD", [i]) +} + +# Do not root +any_user { + input[i].Cmd == "user" + } + +deny_root_user[msg] { + not any_user + msg = "Do not run as root, use USER instead" +} + +# Do not sudo +deny[msg] { + input[i].Cmd == "run" + val := concat(" ", input[i].Value) + contains(lower(val), "sudo") + msg = sprintf("Line %d: Do not use 'sudo' command", [i]) +} + +exception[rules] { + input[i].Cmd == "from" + input[i].Value[0] == "nginxinc/nginx-unprivileged:stable-alpine" + + rules := ["root_user", "untrusted_base_image"] +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8049c68 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..a69d9cb --- /dev/null +++ b/gradlew @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f127cfd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,91 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 443a022..0000000 --- a/pom.xml +++ /dev/null @@ -1,161 +0,0 @@ - - 4.0.0 - lodview - lodview - 1.2.1-SNAPSHOT - war - lodview - lodview - - UTF-8 - 1.7 - 4.2.4.RELEASE - 1.8.1 - 1.6.1 - - - - org.apache.jena - apache-jena-libs - pom - 2.13.0 - - - - - org.springframework - spring-context - ${org.springframework-version} - - - - commons-logging - commons-logging - - - - - org.springframework - spring-webmvc - ${org.springframework-version} - - - - - org.slf4j - slf4j-api - 1.7.1 - - - org.slf4j - jcl-over-slf4j - 1.7.1 - - - ch.qos.logback - logback-classic - 1.0.7 - - - - - javax.servlet - javax.servlet-api - 3.0.1 - provided - - - javax.servlet.jsp - jsp-api - 2.1 - provided - - - javax.servlet.jsp.jstl - jstl-api - 1.2 - - - javax.servlet - servlet-api - - - - - org.glassfish.web - jstl-impl - 1.2 - - - javax.servlet - servlet-api - - - - - - - - org.apache.commons - commons-lang3 - 3.3.1 - - - org.springframework.boot - spring-boot-starter-integration - 1.1.4.RELEASE - - - - - ${project.artifactId} - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - ${java-version} - ${java-version} - - - - org.apache.maven.plugins - maven-dependency-plugin - - - install - install - - sources - - - - - - org.apache.tomcat.maven - tomcat7-maven-plugin - 2.2 - - - org.eclipse.jetty - jetty-maven-plugin - 9.2.7.v20150116 - - - /${project.artifactId} - - - - - - - - io.spring.repo.maven.milestone - http://repo.spring.io/milestone/ - - false - - - - diff --git a/publiccode.yml b/publiccode.yml new file mode 100644 index 0000000..b025e73 --- /dev/null +++ b/publiccode.yml @@ -0,0 +1,74 @@ +# This repository adheres to the publiccode.yml standard by including this +# metadata file that makes public software easily discoverable. +# More info at https://github.com/italia/publiccode.yml + +publiccodeYmlVersion: '0.2' +applicationSuite: NDC +categories: + - data-analytics + - data-collection + - digital-asset-management +description: + it: + features: + - viewer + genericName: dati-semantic-lodview + longDescription: |- + Questo repository contiene il visualizzatore di asset semantici + (ontologie e vocabolari controllati) + per il National Data Catalog for Semantic Interoperability. + + Il viewer è un fork aggiornato di https://github.com/LodLive/LodView/ e + visualizza gli asset semantici richiesti interrogando un server SparQL da configurare + in fase di deployment. + + Permette inoltre di convertire in JSON-LD ed altri formati le informazioni + recuperate da SparQL. + shortDescription: Visualizzatore di ontologie e vocabolari per il repository semantico del NDC +developmentStatus: beta +intendedAudience: + scope: + - government + - research + - science-and-technology +isBasedOn: + - https://github.com/LodLive/LodView/ +it: + conforme: + gdpr: false + lineeGuidaDesign: false + misureMinimeSicurezza: false + modelloInteroperabilita: true + countryExtensionVersion: '0.2' + piattaforme: + anpr: false + cie: false + pagopa: false + spid: false + riuso: + codiceIPA: pcm +legal: + license: MIT + mainCopyrightOwner: Dipartimento per la Trasformazione Digitale + repoOwner: Dipartimento per la Trasformazione Digitale +localisation: + availableLanguages: + - en + localisationReady: false +maintenance: + contacts: + - affiliation: ISTAT + email: polizzi@istat.it + name: Marco Polizzi + contractors: + - name: ISTAT + until: '2026-12-31' + type: contract +name: LodView +platforms: + - linux + - web +releaseDate: '2021-12-25' +softwareType: standalone/other +url: 'https://github.com/teamdigitale/dati-semantic-lodview' +logo: src/main/resources/static/staticResources/img/logo-footer-lodview.png diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..63a16d7 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'lodview-ng' diff --git a/src/main/java/it/gov/innovazione/lodviewng/LodviewNgApplication.java b/src/main/java/it/gov/innovazione/lodviewng/LodviewNgApplication.java new file mode 100644 index 0000000..d37518f --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/LodviewNgApplication.java @@ -0,0 +1,20 @@ +package it.gov.innovazione.lodviewng; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class LodviewNgApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(LodviewNgApplication.class, args); + } + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + return builder.sources(LodviewNgApplication.class); + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/bean/OntologyBean.java b/src/main/java/it/gov/innovazione/lodviewng/bean/OntologyBean.java new file mode 100644 index 0000000..f7c6f2e --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/bean/OntologyBean.java @@ -0,0 +1,82 @@ +package it.gov.innovazione.lodviewng.bean; + + +import it.gov.innovazione.lodviewng.utils.ResourceClassPathLoader; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; +import org.apache.jena.rdf.model.Literal; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.NodeIterator; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.util.FileManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.File; +import java.util.List; + +@Component +@Slf4j +public class OntologyBean { + + private static final String DEFAULT_VALUE = ""; + @Getter + private final Model model = ModelFactory.createDefaultModel(); + @Value("${lode.ontoDir}") + private String ontoDir; + + @PostConstruct + void init() { + List ontologies = ResourceClassPathLoader.toFiles(ontoDir); + + if (ontologies.isEmpty()) { + log.debug("no ontologies found in directory " + ontoDir); + return; + } + + ontologies.forEach(file -> { + if (!file.isDirectory()) { + try { + log.info("Parsing ontology " + file.getName()); + log.debug("loading " + file.getCanonicalPath()); + FileManager.get().readModel(model, file.getAbsolutePath()); + log.debug("read successfully!"); + } catch (Exception e) { + log.error("error loading " + e.getMessage()); + } + } + }); + } + + public String getValue(String what, String preferredLanguage, String iri) { + Resource resource = model.createResource(iri); + return getSingleValue(preferredLanguage, resource, "http://www.w3.org/2000/01/rdf-schema#" + what); + } + + public String getEscapedValue(String what, String preferredLanguage, String iri) { + return StringEscapeUtils.escapeHtml4(getValue(what, preferredLanguage, iri)); + } + + private String getSingleValue(String preferredLanguage, Resource iri, String prop) { + NodeIterator iter = model.listObjectsOfProperty(iri, model.createProperty(prop)); + String result = DEFAULT_VALUE; + boolean betterTitleMatch = false; + while (iter.hasNext()) { + RDFNode node = iter.nextNode(); + Literal l = node.asLiteral(); + if (!betterTitleMatch && (result.equals(DEFAULT_VALUE) || l.getLanguage().equals("en") || l.getLanguage().equals(preferredLanguage))) { + if (preferredLanguage.equals(l.getLanguage())) { + betterTitleMatch = true; + } + result = l.getLexicalForm(); + } + + } + return result; + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/bean/PropertyBean.java b/src/main/java/it/gov/innovazione/lodviewng/bean/PropertyBean.java new file mode 100644 index 0000000..7f57961 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/bean/PropertyBean.java @@ -0,0 +1,12 @@ +package it.gov.innovazione.lodviewng.bean; + +import lombok.Data; + +@Data +public class PropertyBean { + private String nsProperty; + private String property; + private String propertyUrl; + private String label = ""; + private String comment = ""; +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/bean/ResultBean.java b/src/main/java/it/gov/innovazione/lodviewng/bean/ResultBean.java new file mode 100644 index 0000000..2014e28 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/bean/ResultBean.java @@ -0,0 +1,113 @@ +package it.gov.innovazione.lodviewng.bean; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Data +public class ResultBean { + + private String title; + private String latitude; + private String longitude; + private String mainIRI; + private PropertyBean descriptionProperty; + private PropertyBean typeProperty; + private List images; + private List linking; + private List videos; + private List audios; + private Map>> literals = new HashMap<>(); + private Map>> resources = new HashMap<>(); + private Map>> bnodes = new HashMap<>(); + + private void addEle(String iri, TripleBean tripleBean, Map>> ele) { + if (ele.get(iri) == null || ele.get(iri).get(tripleBean.getProperty()) == null) { + Map> a = ele.get(iri); + if (a == null) { + a = new LinkedHashMap<>(); + } + List b = new ArrayList<>(); + b.add(tripleBean); + a.put(tripleBean.getProperty(), b); + ele.put(iri, a); + } else { + Map> a = ele.get(iri); + List b = a.get(tripleBean.getProperty()); + b.add(tripleBean); + a.put(tripleBean.getProperty(), b); + ele.put(iri, a); + } + } + + private void removeEle(String iri, TripleBean tripleBean, Map>> ele) { + if (!(ele.get(iri) == null || ele.get(iri).get(tripleBean.getProperty()) == null)) { + Map> a = ele.get(iri); + List b = a.get(tripleBean.getProperty()); + b.remove(tripleBean); + a.put(tripleBean.getProperty(), b); + ele.put(iri, a); + } + } + + public void setLiterals(String iri, List localLiterals) { + for (TripleBean tripleBean : localLiterals) { + addEle(iri, tripleBean, literals); + } + } + + public void setBnodes(String iri, List localBnodes) { + for (TripleBean tripleBean : localBnodes) { + addEle(iri, tripleBean, bnodes); + } + } + + public void setResources(String iri, List localResources) { + for (TripleBean tripleBean : localResources) { + addEle(iri, tripleBean, resources); + } + } + + public Map> getResources(String iri) { + return resources.get(iri); + } + + public Map> getLiterals(String iri) { + return literals.get(iri); + } + + public Map> getBnodes(String IRI) { + return bnodes.get(IRI); + } + + public void addBnode(TripleBean tripleBean, String iri) { + addEle(iri, tripleBean, bnodes); + } + + public void addLiteral(TripleBean tripleBean, String iri) { + addEle(iri, tripleBean, literals); + } + + public void addResource(TripleBean tripleBean, String iri) { + addEle(iri, tripleBean, resources); + } + + public void removeBnode(TripleBean tripleBean, String iri) { + + removeEle(iri, tripleBean, bnodes); + } + + public void removeLiteral(TripleBean tripleBean, String iri) { + removeEle(iri, tripleBean, literals); + + } + + public void removeResource(TripleBean tripleBean, String iri) { + removeEle(iri, tripleBean, resources); + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/bean/TripleBean.java b/src/main/java/it/gov/innovazione/lodviewng/bean/TripleBean.java new file mode 100644 index 0000000..e7ddf1f --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/bean/TripleBean.java @@ -0,0 +1,18 @@ +package it.gov.innovazione.lodviewng.bean; + +import lombok.Data; + +@Data +public class TripleBean { + private PropertyBean property; + private String nsValue; + private String type; + private String iri; + private String nsIri; + private String value; + private String dataType; + private String nsDataType; + private String lang; + private String url; + private boolean isLocal = false; +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/builder/ResourceBuilder.java b/src/main/java/it/gov/innovazione/lodviewng/builder/ResourceBuilder.java new file mode 100644 index 0000000..9acd21f --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/builder/ResourceBuilder.java @@ -0,0 +1,330 @@ +package it.gov.innovazione.lodviewng.builder; + + +import it.gov.innovazione.lodviewng.endpoint.SPARQLEndPoint; +import it.gov.innovazione.lodviewng.bean.OntologyBean; +import it.gov.innovazione.lodviewng.bean.ResultBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import it.gov.innovazione.lodviewng.utils.Misc; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.RDFWriterI; +import org.apache.jena.riot.Lang; +import org.springframework.context.MessageSource; + +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +@NoArgsConstructor +@AllArgsConstructor +public class ResourceBuilder { + + public static final String ERROR_NO_CONTENT_NEGOTIATION = "error.noContentNegotiation"; + public static final String SORRY_BUT_CONTENT_NEGOTIATION_IS_NOT_SUPPORTED_BY_THE_IRI = "sorry but content negotiation is not supported by the IRI"; + public static final String LITERAL = "literal"; + public static final String IRI = "iri"; + public static final String BNODE = "bnode"; + public static final String SHOW_XML_DECLARATION = "showXMLDeclaration"; + public static final String RELATIVE_URIS = "relativeURIs"; + private MessageSource messageSource; + + public ResultBean buildHtmlResource(String iri, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { + return buildHtmlResource(iri, locale, conf, ontoBean, false); + } + + public ResultBean buildHtmlResource(String iri, Locale locale, ConfigurationBean conf, OntologyBean ontoBean, boolean localMode) throws Exception { + ResultBean result = new ResultBean(); + List videos = new ArrayList<>(); + List audios = new ArrayList<>(); + List images = new ArrayList<>(); + List linking = new ArrayList<>(); + SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); + result.setMainIRI(iri); + + String preferredLanguage = conf.getPreferredLanguage(); + if (preferredLanguage.equals("auto")) { + preferredLanguage = locale.getLanguage(); + } + List triples; + if (conf.getEndPointUrl() != null && conf.getEndPointUrl().equals("<>")) { + localMode = true; + } + if (localMode) { + /* looking for data via content negotiation */ + Model m = ModelFactory.createDefaultModel(); + try { + m.read(iri); + } catch (Exception e) { + throw new Exception(messageSource.getMessage(ERROR_NO_CONTENT_NEGOTIATION, null, SORRY_BUT_CONTENT_NEGOTIATION_IS_NOT_SUPPORTED_BY_THE_IRI, locale)); + } + triples = se.doLocalQuery(m, iri, conf.getDefaultQueries()); + } else { + triples = se.doQuery(iri, conf.getDefaultQueries(), null); + } + boolean betterTitleMatch = false; + boolean betterDescrMatch = false; + for (TripleBean tripleBean : triples) { + + if (tripleBean.getIri() == null) { + tripleBean.setIri(iri); + tripleBean.setNsIri(Misc.toNsResource(tripleBean.getIri(), conf)); + } + + if (conf.getTitleProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getTitleProperties().contains(tripleBean.getProperty().getProperty())) { + if (tripleBean.getIri().equals(iri) && !betterTitleMatch && (result.getTitle() == null || result.getTitle().trim().equals("") || (tripleBean.getLang() != null && (preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))))) { + result.setTitle(Misc.stripHTML(tripleBean.getValue())); + if (preferredLanguage.equals(tripleBean.getLang())) { + betterTitleMatch = true; + } + } + } else if (conf.getDescriptionProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getDescriptionProperties().contains(tripleBean.getProperty().getProperty())) { + if (tripleBean.getIri().equals(iri) && !betterDescrMatch && (result.getDescriptionProperty() == null || (tripleBean.getLang() != null && (preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))))) { + result.setDescriptionProperty(tripleBean.getProperty()); + if (preferredLanguage.equals(tripleBean.getLang())) { + betterDescrMatch = true; + } + } + } else if (conf.getLatitudeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLatitudeProperties().contains(tripleBean.getProperty().getProperty())) { + result.setLatitude(tripleBean.getValue()); + } else if (conf.getLongitudeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLongitudeProperties().contains(tripleBean.getProperty().getProperty())) { + result.setLongitude(tripleBean.getValue()); + } else if (conf.getImageProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getImageProperties().contains(tripleBean.getProperty().getProperty())) { + images.add(tripleBean.getValue()); + } else if (conf.getAudioProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getAudioProperties().contains(tripleBean.getProperty().getProperty())) { + audios.add(tripleBean.getValue()); + } else if (conf.getVideoProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getVideoProperties().contains(tripleBean.getProperty().getProperty())) { + videos.add(tripleBean.getValue()); + } else if (conf.getLinkingProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLinkingProperties().contains(tripleBean.getProperty().getProperty())) { + linking.add(tripleBean.getValue()); + } else if (conf.getTypeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getTypeProperties().contains(tripleBean.getProperty().getProperty())) { + result.setTypeProperty(tripleBean.getProperty()); + } + + if (tripleBean.getType().equals(IRI)) { + tripleBean.setUrl(Misc.toBrowsableUrl(tripleBean.getValue(), conf)); + tripleBean.setNsValue(Misc.toNsResource(tripleBean.getValue(), conf)); + if (!tripleBean.getUrl().equals(tripleBean.getValue()) || tripleBean.getValue().startsWith(conf.getPublicUrlPrefix())) { + tripleBean.setLocal(true); + } + result.addResource(tripleBean, tripleBean.getIri()); + } else if (tripleBean.getType().equals(LITERAL)) { + result.addLiteral(tripleBean, tripleBean.getIri()); + } else if (tripleBean.getType().equals(BNODE)) { + result.addBnode(tripleBean, tripleBean.getIri()); + } + } + + result.setImages(images); + result.setLinking(linking); + result.setVideos(videos); + result.setAudios(audios); + + return result; + } + + public String buildRDFResource(String iri, String sparql, Lang lang, ConfigurationBean conf) throws Exception { + String result; + Model model = ModelFactory.createDefaultModel(); + model.setNsPrefixes(conf.getPrefixes()); + + SPARQLEndPoint se = new SPARQLEndPoint(conf, null, null); + model = se.extractData(model, iri, sparql, conf.getDefaultRawDataQueries()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + RDFWriterI rdfWriter = model.getWriter(lang.getName()); + rdfWriter.setProperty(SHOW_XML_DECLARATION, "true"); + rdfWriter.setProperty(RELATIVE_URIS, ""); + + rdfWriter.write(model, baos, conf.getIRInamespace()); + + result = baos.toString(StandardCharsets.UTF_8); + + return result; + } + + public String buildRDFResource(String iri, Model m, Lang lang, ConfigurationBean conf) throws Exception { + String result; + Model model = ModelFactory.createDefaultModel(); + model.setNsPrefixes(conf.getPrefixes()); + + SPARQLEndPoint se = new SPARQLEndPoint(conf, null, null); + model = se.extractLocalData(model, iri, m, conf.getDefaultRawDataQueries()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + RDFWriterI rdfWriter = model.getWriter(lang.getName()); + rdfWriter.setProperty(SHOW_XML_DECLARATION, "true"); + rdfWriter.setProperty(RELATIVE_URIS, ""); + + rdfWriter.write(model, baos, conf.getIRInamespace()); + rdfWriter.setProperty(SHOW_XML_DECLARATION, "true"); + rdfWriter.setProperty(RELATIVE_URIS, ""); + + result = baos.toString(StandardCharsets.UTF_8); + + return result; + } + + public ResultBean buildPartialHtmlResource(String iri, String[] abouts, Locale locale, ConfigurationBean conf, OntologyBean ontoBean, List filterProperties) { + + SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); + ResultBean result = new ResultBean(); + List literals = new ArrayList<>(); + + String preferredLanguage = conf.getPreferredLanguage(); + if (preferredLanguage.equals("auto")) { + preferredLanguage = locale.getLanguage(); + } + + List triples = new ArrayList<>(); + + /* + * FIXME: make more distinct queries to avoid length limits, eg + * http://dati.camera.it/ocd/assemblea.rdf/a16 + */ + + StringBuilder filter = new StringBuilder(); + for (String titleProperty : filterProperties) { + if (titleProperty.toLowerCase().startsWith("http:")) { + filter.append("(?filterProperty = <").append(titleProperty).append(">)"); + } else { + filter.append("(?filterProperty = ").append(titleProperty).append(")"); + } + filter.append(" || "); + } + + for (String about : abouts) { + List sparqlQueries = new ArrayList<>(); + sparqlQueries.add(("select distinct ?o " + "{ <" + about + "> ?filterProperty ?o. FILTER (" + filter + "))} ").replaceAll("\\|\\| \\)", "")); + try { + + if (conf.getEndPointUrl().equals("<>")) { + /* looking for data via content negotiation */ + Model m = ModelFactory.createDefaultModel(); + try { + m.read(about); + } catch (Exception e) { + throw new Exception(messageSource.getMessage(ERROR_NO_CONTENT_NEGOTIATION, null, SORRY_BUT_CONTENT_NEGOTIATION_IS_NOT_SUPPORTED_BY_THE_IRI, locale)); + } + triples.addAll(se.doLocalQuery(m, about, sparqlQueries, about)); + } else { + triples.addAll(se.doQuery(null, sparqlQueries, about)); + } + + } catch (Exception e) { + } + } + + Map> l = new HashMap<>(); + + for (TripleBean tripleBean : triples) { + if (tripleBean.getType().equals(LITERAL)) { + List al = l.get(tripleBean.getProperty().getProperty()); + if (al == null) { + al = new ArrayList<>(); + } + al.add(tripleBean); + l.put(tripleBean.getProperty().getProperty(), al); + } + } + + for (Map.Entry> about : l.entrySet()) { + List al = about.getValue(); + boolean betterTitleMatch = false; + TripleBean title = null; + for (TripleBean tripleBean : al) { + if (!betterTitleMatch && (title == null || title.getValue() == null || title.getValue().trim().equals("") || preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))) { + title = tripleBean; + if (preferredLanguage.equals(tripleBean.getLang())) { + betterTitleMatch = true; + } + } + } + if (title != null) { + literals.add(title); + } + } + result.setLiterals(iri, literals); + return result; + } + + public ResultBean buildHtmlInverseResource(String iri, String property, int start, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { + ResultBean result = new ResultBean(); + + SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); + String preferredLanguage = conf.getPreferredLanguage(); + if (preferredLanguage.equals("auto")) { + preferredLanguage = locale.getLanguage(); + } + if (property == null) { + /* counting */ + List resources = new ArrayList<>(); + List triples; + + if (conf.getEndPointUrl().equals("<>")) { + /* looking for data via content negotiation */ + Model m = ModelFactory.createDefaultModel(); + try { + m.read(iri); + } catch (Exception e) { + throw new Exception(messageSource.getMessage(ERROR_NO_CONTENT_NEGOTIATION, null, SORRY_BUT_CONTENT_NEGOTIATION_IS_NOT_SUPPORTED_BY_THE_IRI, locale)); + } + triples = se.doLocalQuery(m, iri, conf.getDefaultInversesCountQueries()); + } else { + triples = se.doQuery(iri, conf.getDefaultInversesCountQueries(), null); + } + + for (TripleBean tripleBean : triples) { + if (tripleBean.getType().equals(LITERAL)) { + resources.add(tripleBean); + } + } + + result.setResources(iri, resources); + + } else { + /* listing */ + List resources = new ArrayList<>(); + List triples; + + if (conf.getEndPointUrl().equals("<>")) { + /* looking for data via content negotiation */ + Model m = ModelFactory.createDefaultModel(); + try { + m.read(iri); + } catch (Exception e) { + throw new Exception(messageSource.getMessage(ERROR_NO_CONTENT_NEGOTIATION, null, SORRY_BUT_CONTENT_NEGOTIATION_IS_NOT_SUPPORTED_BY_THE_IRI, locale)); + } + triples = se.doLocalQuery(m, iri, property, start, conf.getDefaultInversesQueries(), null); + } else { + triples = se.doQuery(iri, property, start, conf.getDefaultInversesQueries(), null, null); + } + + Map controlList = new HashMap<>(); + for (TripleBean tripleBean : triples) { + if (tripleBean.getType().equals(LITERAL)) { + if (controlList.get(tripleBean.getProperty().getProperty()) == null || preferredLanguage.equals(tripleBean.getLang())) { + controlList.put(tripleBean.getProperty().getProperty(), tripleBean); + } + } + } + + controlList.forEach((ignored, tripleBean) -> resources.add(tripleBean)); + result.setResources(iri, resources); + + } + + return result; + } + + public ResultBean buildHtmlInverseResource(String iri, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { + return buildHtmlInverseResource(iri, null, -1, locale, conf, ontoBean); + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBean.java b/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBean.java new file mode 100644 index 0000000..a51e6e4 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBean.java @@ -0,0 +1,228 @@ +package it.gov.innovazione.lodviewng.conf; + + +import it.gov.innovazione.lodviewng.utils.ResourceClassPathLoader; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.NodeIterator; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.ResIterator; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.riot.RDFDataMgr; +import org.springframework.web.context.ServletContextAware; + +import javax.servlet.ServletContext; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +@Slf4j +@Data +@RequiredArgsConstructor +public class ConfigurationBean implements ServletContextAware, Cloneable { + + private static final Random RAND = new Random(); + protected final String confFile; + protected Model confModel; + protected ServletContext context; + private String endPointType; + private String redirectionStrategy; + private String forceIriEncoding; + private String httpRedirectExcludeList; + private String homeUrl; + private String license; + private String httpRedirectSuffix; + private String httpRedirectPrefix; + private String endPointUrl; + private String IRInamespace; + private String contentEncoding; + private String staticResourceURL; + private String preferredLanguage; + private String publicUrlPrefix; + private String publicUrlSuffix = ""; + private String authUsername; + private String authPassword; + private String defaultInverseBehaviour = "collapse"; + private ColorStrategy colorStrategy = ColorStrategy.RANDOM; + private List defaultQueries; + private List defaultRawDataQueries; + private List defaultInversesQueries; + private List defaultInversesTest; + private List defaultInversesCountQueries; + private List typeProperties; + private List audioProperties; + private List imageProperties; + private List videoProperties; + private List linkingProperties; + private List titleProperties; + private List descriptionProperties; + private List longitudeProperties; + private List latitudeProperties; + private List colorPair; + private List skipDomains; + private List mainOntologiesPrefixes; + private Map colorPairMatcher; + + public ColorStrategy getColorStrategy() { + return colorStrategy; + } + + public void populateBean() throws Exception { + log.debug("Initializing configuration " + confFile); + + confModel = RDFDataMgr.loadModel(ResourceClassPathLoader.toFile("conf/" + confFile).getAbsolutePath()); + + endPointUrl = getSingleConfValue("endpoint"); + endPointType = getSingleConfValue("endpointType", ""); + authPassword = getSingleConfValue("authPassword"); + authUsername = getSingleConfValue("authUsername"); + forceIriEncoding = getSingleConfValue("forceIriEncoding", "auto"); + redirectionStrategy = getSingleConfValue("redirectionStrategy", ""); + + IRInamespace = getSingleConfValue("IRInamespace", ""); + + httpRedirectSuffix = getSingleConfValue("httpRedirectSuffix", ""); + httpRedirectPrefix = getSingleConfValue("httpRedirectPrefix", ""); + httpRedirectExcludeList = getSingleConfValue("httpRedirectExcludeList", ""); + + publicUrlPrefix = getSingleConfValue("publicUrlPrefix", ""); + publicUrlPrefix = publicUrlPrefix.replaceAll("^(.+/)?auto$", context.getContextPath() + "/"); + + contentEncoding = getSingleConfValue("contentEncoding"); + staticResourceURL = getSingleConfValue("staticResourceURL", ""); + homeUrl = getSingleConfValue("homeUrl", "/"); + staticResourceURL = staticResourceURL.replaceAll("^(.+/)?auto$", context.getContextPath() + "/staticResources/"); + + preferredLanguage = getSingleConfValue("preferredLanguage"); + + typeProperties = getMultiConfValue("typeProperties"); + titleProperties = getMultiConfValue("titleProperties"); + descriptionProperties = getMultiConfValue("descriptionProperties"); + imageProperties = getMultiConfValue("imageProperties"); + audioProperties = getMultiConfValue("audioProperties"); + videoProperties = getMultiConfValue("videoProperties"); + linkingProperties = getMultiConfValue("linkingProperties"); + longitudeProperties = getMultiConfValue("longitudeProperties"); + latitudeProperties = getMultiConfValue("latitudeProperties"); + + defaultQueries = getMultiConfValue("defaultQueries"); + defaultRawDataQueries = getMultiConfValue("defaultRawDataQueries"); + + defaultInversesQueries = getMultiConfValue("defaultInversesQueries"); + defaultInversesTest = getMultiConfValue("defaultInversesTest"); + defaultInversesCountQueries = getMultiConfValue("defaultInversesCountQueries"); + + defaultInverseBehaviour = getSingleConfValue("defaultInverseBehaviour", defaultInverseBehaviour); + mainOntologiesPrefixes = getMultiConfValue("mainOntologiesPrefixes"); + + license = getSingleConfValue("license", ""); + + colorPair = getMultiConfValue("colorPair"); + + if (colorPair.size() == 1 && colorPair.get(0).startsWith("http://")) { + String colorPairSuffix = colorPair.get(0).replace("http://lodview.it/conf#", ""); + if ("byClass".equals(colorPairSuffix)) { + colorStrategy = ColorStrategy.CLASS; + } else if ("byPrefix".equals(colorPairSuffix)) { + colorStrategy = ColorStrategy.PREFIX; + } + colorPairMatcher = populateColorPairMatcher(); + } + + skipDomains = getMultiConfValue("skipDomains"); + } + + private Map populateColorPairMatcher() { + Map result = new HashMap<>(); + ResIterator iter = confModel.listSubjectsWithProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), "hasColorPair")); + while (iter.hasNext()) { + Resource res = iter.next(); + NodeIterator values = confModel.listObjectsOfProperty(res, confModel.createProperty(confModel.getNsPrefixURI("conf"), "hasColorPair")); + if (values.hasNext()) { + result.put(res.toString(), values.next().toString()); + } + } + return result; + } + + private String getSingleConfValue(String prop) { + return getSingleConfValue(prop, null); + } + + private String getSingleConfValue(String prop, String defaultValue) { + String value = System.getenv("LodView" + prop); + if (value != null) { + return value; + } + NodeIterator iter = confModel.listObjectsOfProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), prop)); + if (iter.hasNext()) { + return iter.next().toString(); + } + return defaultValue; + } + + private List getMultiConfValue(String prop) { + List result = new ArrayList<>(); + NodeIterator iter = confModel.listObjectsOfProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), prop)); + while (iter.hasNext()) { + RDFNode node = iter.next(); + result.add(node.toString()); + } + return result; + } + + @Override + public void setServletContext(ServletContext arg0) { + this.context = arg0; + try { + populateBean(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public Map getPrefixes() { + return confModel.getNsPrefixMap(); + } + + public String getNsPrefixURI(String prefix) { + return confModel.getNsPrefixURI(prefix); + } + + public String getNsURIPrefix(String iri) { + return confModel.getNsURIPrefix(iri); + } + + public String getRandomColorPair() { + if (colorStrategy != ColorStrategy.RANDOM) { + return "#914848-#7d3e3e"; + } + int randomNum = RAND.nextInt(colorPair.size()); + return colorPair.get(randomNum); + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error("Something impossible just happened"); + } + } + + public String getForceIriEncoding() { + return forceIriEncoding; + } + + public String getEndPointType() { + return endPointType; + } + + public enum ColorStrategy {RANDOM, CLASS, PREFIX} + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBeanConfig.java b/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBeanConfig.java new file mode 100644 index 0000000..3bbc401 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/conf/ConfigurationBeanConfig.java @@ -0,0 +1,18 @@ +package it.gov.innovazione.lodviewng.conf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ConfigurationBeanConfig { + + @Bean + public ConfigurationBean conf() { + return new ConfigurationBean("conf.ttl"); + } + + @Bean + public ConfigurationBean confLinked() { + return new ConfigurationBean("conf-linked.ttl"); + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/ErrorController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/ErrorController.java new file mode 100644 index 0000000..2194d4d --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/ErrorController.java @@ -0,0 +1,91 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +@Controller +@Slf4j +@RequiredArgsConstructor +public class ErrorController { + + public static final String COLOR_PAIR = "colorPair"; + private final ConfigurationBean conf; + + /* TODO: change the handler to send "error" param to the client */ + @ResponseStatus(value = HttpStatus.NOT_ACCEPTABLE, reason = "unhandled encoding") + @RequestMapping(value = "/406") + public String error406(HttpServletResponse res, ModelMap model, @CookieValue(value = COLOR_PAIR) String colorPair) { + log.error("not acceptable"); + model.addAttribute("statusCode", "406"); + model.addAttribute("conf", conf); + colors(colorPair, res, model); + res.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); + return "error"; + } + + @RequestMapping(value = "/404") + public String error404(HttpServletResponse res, ModelMap model, @RequestParam(value = "error", defaultValue = "") String error, @CookieValue(value = COLOR_PAIR, defaultValue = "") String colorPair, @RequestParam(value = "IRI", defaultValue = "") String IRI, @RequestParam(value = "endpoint", defaultValue = "") String endpoint) { + log.error("not found " + error + " -- " + IRI + " -- " + endpoint); + /* spring bug? */ + model.addAttribute("IRI", IRI); + model.addAttribute("endpoint", endpoint); + model.addAttribute("error", error); + model.addAttribute("conf", conf); + colors(colorPair, res, model); + model.addAttribute("statusCode", "404"); + res.setStatus(HttpServletResponse.SC_NOT_FOUND); + return "error"; + } + + @RequestMapping(value = "/400") + public String error400(HttpServletResponse res, ModelMap model, @RequestParam(value = "IRI", defaultValue = "") String IRI, @CookieValue(value = COLOR_PAIR, defaultValue = "") String colorPair) { + log.error("error on " + IRI); + /* spring bug? */ + model.addAttribute("IRI", IRI.replaceAll("(http://.+),http://.+", "$1")); + model.addAttribute("conf", conf); + colors(colorPair, res, model); + model.addAttribute("statusCode", "400"); + res.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); + return "error"; + } + + @RequestMapping(value = {"/500", "/error"}) + public String error500(HttpServletResponse res, ModelMap model, @RequestParam(value = "error", defaultValue = "") String error, @CookieValue(value = COLOR_PAIR, defaultValue = "") String colorPair, @RequestParam(value = "IRI", defaultValue = "") String IRI, @RequestParam(value = "endpoint", defaultValue = "") String endpoint) { + log.error("error on " + error + " -- " + IRI + " -- " + endpoint); + /* spring bug? */ + model.addAttribute("IRI", IRI); + model.addAttribute("endpoint", endpoint); + model.addAttribute("error", error); + model.addAttribute("conf", conf); + colors(colorPair, res, model); + model.addAttribute("statusCode", "500"); + res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + return "error"; + } + + private void colors(String colorPair, HttpServletResponse res, ModelMap model) { + if (colorPair.equals("")) { + colorPair = conf.getRandomColorPair(); + Cookie c = new Cookie(COLOR_PAIR, colorPair); + c.setPath("/"); + res.addCookie(c); + } + if (conf != null && conf.getColorPairMatcher() != null && conf.getColorPairMatcher().size() > 0) { + model.addAttribute(COLOR_PAIR, conf.getColorPairMatcher().get("http://lodview.it/conf#otherClasses")); + } else { + model.addAttribute(COLOR_PAIR, colorPair); + } + + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/LinkedResourcesController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/LinkedResourcesController.java new file mode 100644 index 0000000..a0340bb --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/LinkedResourcesController.java @@ -0,0 +1,134 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.builder.ResourceBuilder; +import it.gov.innovazione.lodviewng.bean.OntologyBean; +import it.gov.innovazione.lodviewng.bean.PropertyBean; +import it.gov.innovazione.lodviewng.bean.ResultBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import it.gov.innovazione.lodviewng.utils.Misc; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.RequestMapping; +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.util.List; +import java.util.Locale; +import java.util.Map; + +import static org.apache.commons.text.StringEscapeUtils.escapeHtml4; +import static org.apache.commons.text.StringEscapeUtils.escapeXml11; + +@Controller +@RequiredArgsConstructor +@Slf4j +public class LinkedResourcesController { + + public static final String ERROR_LINKED_RESOURCE_UNAVAILABLE = "error.linkedResourceUnavailable"; + public static final String UNABLE_TO_RETRIEVE_DATA = "unable to retrieve data"; + public static final String ROOT = ""; + public static final String RESOURCE_ABOUT = "\n"); + try { + ResultBean results = new ResourceBuilder(messageSource).buildPartialHtmlResource(IRI, abouts, locale, conf, null, conf.getTitleProperties()); + Map> literals = results.getLiterals(IRI); + if (literals == null || literals.size() == 0) { + return ("" + messageSource.getMessage("error.noLiteral", null, "no literal values where found", locale) + ""); + } + for (Map.Entry> literal : literals.entrySet()) { + for (TripleBean tripleBean : literal.getValue()) { + result.append(RESOURCE_ABOUT) + .append(escapeXml11(tripleBean.getProperty().getProperty())) + .append(NSABOUT) + .append(escapeXml11(tripleBean.getProperty().getNsProperty())) + .append("\"><![CDATA[") + .append(escapeHtml4(Misc.stripHTML(tripleBean.getValue()))) + .append("]]>\n"); + } + } + result.append(ROOT); + return result.toString(); + } catch (Exception e) { + // 404? + return ("" + messageSource.getMessage(ERROR_LINKED_RESOURCE_UNAVAILABLE, null, UNABLE_TO_RETRIEVE_DATA, locale) + "" + e.getMessage() + ""); + } + } + + @ResponseBody + @RequestMapping(value = "/linkedResourceInverses", produces = "application/xml;charset=UTF-8") + public String resourceInversesController(ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "property", defaultValue = "") String property, @RequestParam(value = "start", defaultValue = "-1") int start) throws Exception { + return resourceInverses(model, conf, ontoBean, req, res, locale, IRI, property, start); + } + + public String resourceInverses(ModelMap model, ConfigurationBean conf, OntologyBean ontoBean, HttpServletRequest req, HttpServletResponse res, Locale locale, String IRI, String property, int start) throws Exception { + StringBuilder result = new StringBuilder("\n"); + if (property.equals("")) { + try { + ResultBean results = new ResourceBuilder(messageSource).buildHtmlInverseResource(IRI, locale, conf, ontoBean); + Map> resources = results.getResources(IRI); + if (resources != null) { + for (Map.Entry> resource : resources.entrySet()) { + for (TripleBean tripleBean : resource.getValue()) { + if (tripleBean.getProperty().getProperty() == null || tripleBean.getProperty().getProperty().equals("")) { + throw new Exception("no content"); + } + result.append(RESOURCE_ABOUT).append(escapeXml11(tripleBean.getProperty().getProperty())) + .append(NSABOUT).append(escapeXml11(tripleBean.getProperty().getNsProperty())) + .append("\" propertyurl=\"").append(escapeXml11(tripleBean.getProperty().getPropertyUrl())) + .append("\" propertylabel=\"").append(escapeXml11(Misc.stripHTML(tripleBean.getProperty().getLabel()))) + .append("\" propertycomment=\"").append(escapeXml11(tripleBean.getProperty().getComment())) + .append("\" >\n"); + } + } + } + + result.append(ROOT); + return result.toString(); + + } catch (Exception e) { + return ("" + messageSource.getMessage(ERROR_LINKED_RESOURCE_UNAVAILABLE, null, UNABLE_TO_RETRIEVE_DATA, locale) + "" + e.getMessage() + ""); + } + } else { + + /* retrieving inverse relations */ + try { + ResultBean results = new ResourceBuilder(messageSource).buildHtmlInverseResource(IRI, property, start, locale, conf, null); + Map> resources = results.getResources(IRI); + for (Map.Entry> resource : resources.entrySet()) { + for (TripleBean tripleBean : resource.getValue()) { + result.append(RESOURCE_ABOUT).append(escapeXml11(tripleBean.getProperty().getProperty())) + .append(NSABOUT).append(escapeXml11(tripleBean.getProperty().getNsProperty())) + .append("\" propertyurl=\"").append(escapeXml11(tripleBean.getProperty().getPropertyUrl())) + .append("\" >\n"); + } + } + + result.append(ROOT); + return result.toString(); + + } catch (Exception e) { + e.printStackTrace(); + return ("" + messageSource.getMessage(ERROR_LINKED_RESOURCE_UNAVAILABLE, null, UNABLE_TO_RETRIEVE_DATA, locale) + ""); + } + } + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/LodController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/LodController.java new file mode 100644 index 0000000..b0eed32 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/LodController.java @@ -0,0 +1,91 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.bean.ResultBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.builder.ResourceBuilder; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; +import org.springframework.context.MessageSource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +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.util.List; +import java.util.Locale; + +@Controller +@RequiredArgsConstructor +@Slf4j +public class LodController { + + public static final String LOD_CONTROLLER_RESOURCE_LOAD = " LodController.resource() - load - "; + private final ConfigurationBean confLinked; + private final MessageSource messageSource; + + + @ResponseBody + @RequestMapping(value = {"/linkedResource", "/lodview/linkedResource"}, produces = "application/xml;charset=UTF-8") + public String resource(HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI) throws Exception { + + if (confLinked.getSkipDomains().contains(IRI.replaceAll("http[s]*://([^/]+)/.*", "$1"))) { + return "" + // + StringEscapeUtils.escapeXml11(messageSource.getMessage("error.skipedDomain", null, "skiping this URI", locale)) + // + ""; + } + try { + log.info(LOD_CONTROLLER_RESOURCE_LOAD + IRI); + + ResultBean results = new ResourceBuilder(messageSource).buildHtmlResource(IRI, locale, confLinked, null, true); + + StringBuilder result = new StringBuilder("\n"); + + result.append("<![CDATA[" + StringEscapeUtils.escapeHtml4(results.getTitle()) + "]]>"); + + String lang = locale.getLanguage().toLowerCase(); + String descr = ""; + List descrProperties = results.getLiterals(IRI).get(results.getDescriptionProperty()); + if (descrProperties != null) { + for (TripleBean tripleBean : descrProperties) { + if (lang.equals(tripleBean.getLang())) { + descr = tripleBean.getValue(); + lang = tripleBean.getLang(); + break; + } else if (tripleBean.getLang().equals("en")) { + lang = tripleBean.getLang(); + descr = tripleBean.getValue(); + } else if (descr.equals("")) { + descr = tripleBean.getValue(); + lang = tripleBean.getLang(); + } + } + } + + result.append(""); + + for (String img : results.getImages()) { + result.append(""); + } + for (String link : results.getLinking()) { + result.append(""); + } + result.append(""); + result.append(""); + result.append(""); + + result.append(""); + return result.toString(); + + } catch (Exception e) { + // e.printStackTrace(); + log.error(IRI + " unable to retrieve data " + e.getMessage()); + return "" + // + messageSource.getMessage("error.linkedResourceUnavailable", null, "unable to retrieve data", locale) + // + ""; + } + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/ResourceController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/ResourceController.java new file mode 100644 index 0000000..be11262 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/ResourceController.java @@ -0,0 +1,394 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.bean.OntologyBean; +import it.gov.innovazione.lodviewng.bean.ResultBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.builder.ResourceBuilder; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import it.gov.innovazione.lodviewng.utils.Misc; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.jena.atlas.web.AcceptList; +import org.apache.jena.atlas.web.MediaType; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFLanguages; +import org.springframework.context.MessageSource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.view.RedirectView; +import org.springframework.web.util.UrlPathHelper; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +@Controller +@RequestMapping(value = "/") +@RequiredArgsConstructor +@Slf4j +public class ResourceController { + + final AcceptList offeringRDF = new AcceptList("text/turtle, application/turtle, " // + + "application/x-turtle, application/rdf+xml, " // + + "application/rdf+json, application/ld+json, " // + + "text/plain, application/n-triples, text/trig, " // + + "application/n-quads, application/x-trig, application/trig, " // + + "text/n-quads, text/nquads, application/trix+xml, " // + + "text/rdf+n3, application/n3, " // + + "text/n3"); + final AcceptList offeringResources = new AcceptList("text/html, application/xhtml+xml"); + private final ConfigurationBean conf; + private final OntologyBean ontoBean; + private final MessageSource messageSource; + + @RequestMapping(value = {"{path:(?!staticResources).*$}", "{path:(?!staticResources).*$}/**"}) + public Object resourceController(ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "output", defaultValue = "") String output, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) throws UnsupportedEncodingException { + if (colorPair.equals("")) { + colorPair = conf.getRandomColorPair(); + Cookie c = new Cookie("colorPair", colorPair); + c.setPath("/"); + res.addCookie(c); + } + return resource(conf, model, req, res, locale, output, "", colorPair); + } + + public Object resource(ConfigurationBean conf, ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, String output, String forceIRI, String colorPair) throws UnsupportedEncodingException { + + model.addAttribute("conf", conf); + + String IRIsuffix = new UrlPathHelper().getLookupPathForRequest(req).replaceAll("/lodview/", "/"); + String requestUrl = req.getRequestURI(); + + log.info("IRIsuffix " + IRIsuffix); + log.info("requestUrl " + requestUrl); + + model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); + model.addAttribute("locale", locale.getLanguage()); + + boolean redirect = false; + boolean redirected = false; + boolean avoidRedirection = false; + + // managing redirections + if (!conf.getHttpRedirectExcludeList().equals("")) { + String[] excList = conf.getHttpRedirectExcludeList().split(","); + for (String exclude : excList) { + if (requestUrl.matches(exclude)) { + avoidRedirection = true; + break; + } + } + } + if (!avoidRedirection && !conf.getHttpRedirectSuffix().equals("")) { + // 303 dereferencing mode + if (IRIsuffix.matches(".+" + conf.getHttpRedirectSuffix() + "$")) { + // after redirect + IRIsuffix = IRIsuffix.replaceAll(conf.getHttpRedirectSuffix() + "$", ""); + + redirected = true; + } else { + // before redirect + redirect = true; + } + } else if (!avoidRedirection && !conf.getHttpRedirectPrefix().equals("")) { + // 303 dereferencing mode + if (IRIsuffix.matches("^" + conf.getHttpRedirectPrefix() + ".+")) { + // after redirect + IRIsuffix = IRIsuffix.replaceAll("^" + conf.getHttpRedirectPrefix(), ""); + if (conf.getRedirectionStrategy().equals("pubby")) { + IRIsuffix = "/resource/" + IRIsuffix; + IRIsuffix = IRIsuffix.replaceAll("//", "/"); + } + redirected = true; + } else { + // before redirect + redirect = true; + } + } + + IRIsuffix = IRIsuffix.replaceAll("^/", ""); + + String IRIprefix = conf.getIRInamespace().replaceAll("/$", ""); + String IRI = IRIprefix + "/" + IRIsuffix.replaceAll(" ", "%20"); + + if (forceIRI != null && !forceIRI.equals("")) { + IRI = forceIRI; + } + + if (conf.getForceIriEncoding().equals("encode")) { + String[] IRItokens = IRI.split("/"); + for (int i = 0; i < IRItokens.length; i++) { + IRItokens[i] = URLEncoder.encode(IRItokens[i], StandardCharsets.UTF_8); + } + IRI = StringUtils.join("/"); + } else if (conf.getForceIriEncoding().equals("decode")) { + String[] IRItokens = IRI.split("/"); + for (int i = 0; i < IRItokens.length; i++) { + IRItokens[i] = java.net.URLDecoder.decode(IRItokens[i], StandardCharsets.UTF_8); + } + IRI = StringUtils.join("/"); + } + + if (conf.getRedirectionStrategy().equals("pubby")) { + /* + * http://dbpedia.org/data/Barack_Obama.ntriples + * http://dbpedia.org/data/Barack_Obama.n3 + * http://dbpedia.org/data/Barack_Obama.json + * http://dbpedia.org/data/Barack_Obama.rdf + */ + if (requestUrl.matches(".+\\.(ntriples|n3|json|rdf)")) { + String outputType = ""; + String newUrl = requestUrl.replaceFirst("/data/", "/resource/").replaceAll("\\.(ntriples|n3|json|rdf)$", ""); + RedirectView r = new RedirectView(); + r.setExposeModelAttributes(false); + if (requestUrl.endsWith(".ntriples")) { + outputType = "text/plain"; + } else if (requestUrl.endsWith(".n3")) { + outputType = "text/turtle"; + } else if (requestUrl.endsWith(".json")) { + outputType = "application/rdf+json"; + } else if (requestUrl.endsWith(".rdf")) { + outputType = "application/rdf+xml"; + } + r.setUrl(newUrl + "?" + (req.getQueryString() != null ? req.getQueryString() + "&" : "") + "output=" + outputType); + return r; + } + } + + log.info("####################################################################"); + log.info("################# looking for " + IRI + " ################# "); + + String[] acceptedContent = req.getHeader("Accept").split(","); + if (redirected) { + acceptedContent = "text/html".split(","); + } + // log.trace("Accept " + req.getHeader("Accept")); + + AcceptList a = AcceptList.create(acceptedContent); + // log.trace("-- AcceptList: " + a); + // log.trace("-- OffertList: " + offeringRDF); + + MediaType matchItem = AcceptList.match(offeringRDF, a); + Lang lang = matchItem != null ? RDFLanguages.contentTypeToLang(matchItem.getContentTypeStr()) : null; + + // override content negotiation + if (!output.equals("")) { + try { + output = output.replaceAll("([a-zA-Z]) ([a-zA-Z])", "$1+$2"); + a = AcceptList.create(output.split(",")); + matchItem = AcceptList.match(offeringRDF, a); + lang = RDFLanguages.contentTypeToLang(matchItem.getContentTypeStr()); + } catch (Exception e) { + return new ErrorController(conf).error406(res, model, colorPair); + } + log.debug("override content type " + matchItem.getContentTypeStr()); + } + + try { + if (lang == null) { + matchItem = AcceptList.match(offeringResources, a); + // probably you are asking for an HTML page + if (matchItem != null) { + if (redirect && !redirected) { + return redirect(req, IRIsuffix); + } else { + return htmlResource(model, IRI, colorPair, locale, req, res); + } + } else { + return new ErrorController(conf).error406(res, model, colorPair); + } + } else { + return resourceRaw(conf, model, IRI, conf.getEndPointUrl(), matchItem.getContentTypeStr()); + } + } catch (Exception e) { + e.printStackTrace(); + if (e.getMessage() != null && e.getMessage().startsWith("404")) { + return new ErrorController(conf).error404(res, model, e.getMessage(), colorPair, IRI, conf.getEndPointUrl()); + } else { + return new ErrorController(conf).error500(res, model, e.getMessage(), colorPair, IRI, conf.getEndPointUrl()); + } + } + + } + + private String htmlResource(ModelMap model, String IRI, String colorPair, Locale locale, HttpServletRequest req, HttpServletResponse res) throws Exception { + model.addAttribute("contextPath", new UrlPathHelper().getContextPath(req)); + ResultBean r = new ResourceBuilder(messageSource).buildHtmlResource(IRI, locale, conf, ontoBean); + model.addAttribute("colorPair", Misc.guessColor(colorPair, r, conf)); + model.addAttribute("results", Misc.guessClass(r, conf, ontoBean)); + model.addAttribute("ontoBean", ontoBean); + + addDataLinks(IRI, model, req, locale); + addLodliveLink(locale, model, IRI); + enrichResponse(model, r, req, res); + return "resource"; + } + + private void addDataLinks(String IRI, ModelMap model, HttpServletRequest req, Locale locale) throws UnsupportedEncodingException { + + Map> rawdatalinks = new LinkedHashMap>(); + String queryString = (req.getQueryString() != null ? "&" + req.getQueryString().replaceAll("&", "&") : ""); + + if (conf.getRedirectionStrategy().equals("pubby")) { + + Map list = new LinkedHashMap(); + list.put("xml", "?output=" + URLEncoder.encode("application/rdf+xml", StandardCharsets.UTF_8) + queryString); + list.put("ntriples", "?output=" + URLEncoder.encode("text/plain", StandardCharsets.UTF_8) + queryString); + list.put("turtle", "?output=" + URLEncoder.encode("text/turtle", StandardCharsets.UTF_8) + queryString); + list.put("json", "?output=" + URLEncoder.encode("application/rdf+json", StandardCharsets.UTF_8) + queryString); + list.put("ld+json", "?output=" + URLEncoder.encode("application/ld+json", StandardCharsets.UTF_8) + queryString); + rawdatalinks.put("rdf:", list); + + } else { + Map list = new LinkedHashMap(); + list.put("xml", "?output=" + URLEncoder.encode("application/rdf+xml", StandardCharsets.UTF_8) + queryString); + list.put("ntriples", "?output=" + URLEncoder.encode("text/plain", StandardCharsets.UTF_8) + queryString); + list.put("turtle", "?output=" + URLEncoder.encode("text/turtle", StandardCharsets.UTF_8) + queryString); + list.put("ld+json", "?output=" + URLEncoder.encode("application/ld+json", StandardCharsets.UTF_8) + queryString); + rawdatalinks.put(messageSource.getMessage("footer.viewAs", null, "view as", locale), list); + } + + if (conf.getEndPointType().equals("virtuoso")) { + { + Map list = new LinkedHashMap(); + list.put("atom", conf.getEndPointUrl() + "?output=application%2Fatom%2Bxml&query=DESCRIBE+%3C" + IRI + "%3E"); + list.put("json", conf.getEndPointUrl() + "?output=application%2Fodata%2Bjson&query=DESCRIBE+%3C" + IRI + "%3E"); + rawdatalinks.put("odata:", list); + } + { + Map list = new LinkedHashMap(); + list.put("html", conf.getEndPointUrl() + "?output=text%2Fhtml&query=DESCRIBE+%3C" + IRI + "%3E"); + list.put("json", conf.getEndPointUrl() + "?output=application%2Fmicrodata%2Bjson&query=DESCRIBE+%3C" + IRI + "%3E"); + rawdatalinks.put("microdata:", list); + } + { + Map list = new LinkedHashMap(); + list.put("csv", conf.getEndPointUrl() + "?output=text%2Fcsv&query=DESCRIBE+%3C" + IRI + "%3E"); + list.put("cxml", conf.getEndPointUrl() + "?output=format=text%2Fcxml&query=DESCRIBE+%3C" + IRI + "%3E"); + rawdatalinks.put("rawdata:", list); + } + } + model.addAttribute("rawdatalinks", rawdatalinks); + + } + + private RedirectView redirect(HttpServletRequest req, String IRIsuffix) throws UnsupportedEncodingException { + + RedirectView r = new RedirectView(); + // preventing redirect of model attributes + r.setExposeModelAttributes(false); + r.setContentType("text/html"); + r.setHttp10Compatible(false); + if (!conf.getHttpRedirectPrefix().equals("")) { + // prefix mode + String redirectUrl = conf.getHttpRedirectPrefix().replaceAll("^/", ""); + if (conf.getRedirectionStrategy().equals("pubby")) { + r.setUrl(conf.getPublicUrlPrefix() + redirectUrl + IRIsuffix.replaceAll("^resource/", "") + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); + } else { + r.setUrl(conf.getPublicUrlPrefix().replaceAll(IRIsuffix + "$", "") + redirectUrl + IRIsuffix + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); + } + } else { + // suffix mode + String redirectUrl = conf.getHttpRedirectSuffix(); + // String[] redirectUrlArray = redirectUrl.split("/"); + // redirectUrl = ""; + // for (String string : redirectUrlArray) { + // redirectUrl += URLEncoder.encode(string, "UTF-8") + "/"; + // } + // redirectUrl = redirectUrl.replaceAll("/$", ""); + r.setUrl(req.getRequestURL() + redirectUrl + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); + } + + return r; + + } + + private void addLodliveLink(Locale locale, ModelMap model, String IRI) { + if (locale.getLanguage().equals("it")) { + model.addAttribute("lodliveUrl", "http://lodlive.it?" + IRI.replaceAll("#", "%23")); + } else if (locale.getLanguage().equals("fr")) { + model.addAttribute("lodliveUrl", "http://fr.lodlive.it?" + IRI.replaceAll("#", "%23")); + } else if (locale.getLanguage().equals("gl")) { + model.addAttribute("lodliveUrl", "http://gl.lodlive.it?" + IRI.replaceAll("#", "%23")); + } else { + model.addAttribute("lodliveUrl", "http://en.lodlive.it?" + IRI.replaceAll("#", "%23")); + } + } + + private void enrichResponse(ModelMap model, ResultBean r, HttpServletRequest req, HttpServletResponse res) { + + String publicUrl = r.getMainIRI(); + res.addHeader("Link", "<" + publicUrl + ">; rel=\"about\""); + + @SuppressWarnings("unchecked") + Map> rawdatalinks = (LinkedHashMap>) model.get("rawdatalinks"); + + rawdatalinks.values().stream() + .map(Map::entrySet) + .flatMap(Collection::stream) + .forEach(e -> + res.addHeader( + "Link", "<" + e.getValue() + ">;" + + " rel=\"alternate\"; type=\"application/rdf+xml\";" + + " title=\"Structured Descriptor Document (" + e.getKey() + ")\"")); + + try { + for (TripleBean t : r.getResources(r.getMainIRI()).get(r.getTypeProperty())) { + res.addHeader("Link", "<" + t.getProperty().getProperty() + ">; rel=\"type\""); + } + } catch (Exception e) { + // TODO: handle exception + } + } + + @RequestMapping(value = "/rawdata") + public ResponseEntity resourceRawController(ModelMap model, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "sparql") String sparql, @RequestParam(value = "contentType", defaultValue = "application/rdf+xml") String contentType) { + return resourceRaw(conf, model, IRI, sparql, contentType); + } + + public ResponseEntity resourceRaw(ConfigurationBean conf, ModelMap model, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "sparql") String sparql, @RequestParam(value = "contentType", defaultValue = "application/rdf+xml") String contentType) { + // logger.trace("ResourceController.resourceRaw()"); + contentType = contentType.replaceAll("([a-zA-Z]) ([a-zA-Z])", "$1+$2"); + Lang lang = RDFLanguages.contentTypeToLang(contentType); + try { + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", contentType + "; charset=" + conf.getContentEncoding()); + + if (sparql != null && sparql.equals("<>")) { + Model m = ModelFactory.createDefaultModel(); + try { + m.read(IRI); + } catch (Exception e) { + throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", Locale.ENGLISH)); + } + return new ResponseEntity(new ResourceBuilder(messageSource).buildRDFResource(IRI, m, lang, conf), headers, HttpStatus.OK); + } else { + return new ResponseEntity(new ResourceBuilder(messageSource).buildRDFResource(IRI, sparql, lang, conf), headers, HttpStatus.OK); + } + + } catch (Exception e) { + if (e.getMessage() != null && e.getMessage().startsWith("404")) { + return new ResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND); + } else { + return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/SPARQLController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/SPARQLController.java new file mode 100644 index 0000000..a5b5a08 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/SPARQLController.java @@ -0,0 +1,17 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequiredArgsConstructor +public class SPARQLController { + private final ConfigurationBean conf; + + @RequestMapping(value = {"/sparql", "/SPARQL"}) + public String sparql() { + return "redirect:" + conf.getEndPointUrl(); + } +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/controllers/StaticController.java b/src/main/java/it/gov/innovazione/lodviewng/controllers/StaticController.java new file mode 100644 index 0000000..d7457ba --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/controllers/StaticController.java @@ -0,0 +1,73 @@ +package it.gov.innovazione.lodviewng.controllers; + +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.MessageSource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.util.UrlPathHelper; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Locale; + +@Controller +@RequiredArgsConstructor +@Slf4j +public class StaticController { + + + private final ConfigurationBean conf; + + private final MessageSource messageSource; + + @RequestMapping(value = "/") + public String home(HttpServletRequest req, HttpServletResponse res, Model model, Locale locale, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) { + colorPair = conf.getRandomColorPair(); + Cookie c = new Cookie("colorPair", colorPair); + c.setPath("/"); + res.addCookie(c); + model.addAttribute("colorPair", colorPair); + model.addAttribute("conf", conf); + model.addAttribute("locale", locale.getLanguage()); + model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); + log.debug("home controller"); + return "home"; + } + + @RequestMapping(value = "/lodviewmenu") + public String lodviewmenu(Model model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) { + if (colorPair.equals("")) { + colorPair = conf.getRandomColorPair(); + Cookie c = new Cookie("colorPair", colorPair); + c.setPath("/"); + res.addCookie(c); + } + return lodviewmenu(req, res, model, locale, IRI, conf, colorPair); + } + + @RequestMapping(value = {"/lodviewcolor", "/**/lodviewcolor"}) + public ResponseEntity lodviewcolor(Model model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "colorPair") String colorPair) { + Cookie c = new Cookie("colorPair", colorPair); + c.setPath("/"); + res.addCookie(c); + return new ResponseEntity<>(HttpStatus.OK); + } + + public String lodviewmenu(HttpServletRequest req, HttpServletResponse res, Model model, Locale locale, @RequestParam(value = "IRI", defaultValue = "") String IRI, ConfigurationBean conf, String colorPair) { + model.addAttribute("conf", conf); + model.addAttribute("locale", locale.getLanguage()); + model.addAttribute("IRI", IRI); + model.addAttribute("colorPair", colorPair); + model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); + return "menu"; + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/endpoint/SPARQLEndPoint.java b/src/main/java/it/gov/innovazione/lodviewng/endpoint/SPARQLEndPoint.java new file mode 100644 index 0000000..5ce214b --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/endpoint/SPARQLEndPoint.java @@ -0,0 +1,341 @@ +package it.gov.innovazione.lodviewng.endpoint; + + +import it.gov.innovazione.lodviewng.bean.OntologyBean; +import it.gov.innovazione.lodviewng.bean.PropertyBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import it.gov.innovazione.lodviewng.utils.Misc; +import org.apache.jena.graph.Node; +import org.apache.jena.http.auth.AuthEnv; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.RDFNode; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.sparql.exec.http.QueryExecutionHTTP; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +public class SPARQLEndPoint { + + private static final Logger logger = LoggerFactory.getLogger(SPARQLEndPoint.class); + protected ConfigurationBean conf; + OntologyBean ontoBean; + String locale = "en"; + + public SPARQLEndPoint(ConfigurationBean conf, OntologyBean ontoBean, String locale) { + this.locale = locale; + this.ontoBean = ontoBean; + this.conf = conf; + // TODO Auto-generated constructor stub + } + + public List doQuery(String IRI, String aProperty, int start, List queries, String filter, String overrideProperty) throws Exception { + // logger.trace("executing query on " + conf.getEndPointUrl()); + List results = new ArrayList(); + if (conf.getAuthPassword() != null && !conf.getAuthPassword().equals("")) { + AuthEnv.get().registerUsernamePassword(URI.create(conf.getEndPointUrl()), conf.getAuthUsername(), conf.getAuthPassword()); + } + for (String query : queries) { + // logger.trace("-- " + parseQuery(query, IRI, aProperty, + // start, filter)); + QueryExecution qe = QueryExecutionHTTP.create() + .endpoint(conf.getEndPointUrl()) + .query(parseQuery(query, IRI, aProperty, start, filter)) + .build(); + //QueryExecutionFactory.sparqlService(conf.getEndPointUrl(), parseQuery(query, IRI, aProperty, start, filter), auth); + results = moreThenOneQuery(qe, results, 0, overrideProperty); + qe.close(); + } + + if (results.size() == 0) { + if (IRI != null) { + boolean hasInverses = false; + for (String query : conf.getDefaultInversesTest()) { + // logger.trace("query!!! " + parseQuery(query, IRI, + // aProperty, start, filter)); + QueryExecution qe = QueryExecutionHTTP.create() + .endpoint(conf.getEndPointUrl()) + .query(parseQuery(query, IRI, aProperty, start, filter)) + .build(); + if (!hasInverses) { + hasInverses = qe.execAsk(); + } + qe.close(); + } + if (!hasInverses) { + throw new Exception("404 - not found"); + } + } + } + return results; + } + + private List moreThenOneQuery(QueryExecution qe, List results, int retry, String overrideProperty) throws Exception { + + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + TripleBean rb = new TripleBean(); + QuerySolution qs = rs.next(); + String property = ""; + if (overrideProperty != null) { + property = overrideProperty; + } else if (qs.get("p") != null) { + property = qs.get("p").asNode().toString(); + } + + try { + if (qs.get("s") != null && !qs.get("s").asNode().toString().startsWith("http://")) { // probably + // a + // bn + rb.setIri(qs.get("s").asNode().toString()); + rb.setNsIri("_:" + rb.getIri()); + } else if (qs.get("s") != null && qs.get("s").asNode().toString().startsWith("http://")) { + rb.setIri(qs.get("s").asNode().toString()); + rb.setNsIri(Misc.toNsResource(rb.getIri(), conf)); + rb.setUrl(Misc.toBrowsableUrl(rb.getIri(), conf)); + } + + PropertyBean p = new PropertyBean(); + p.setNsProperty(Misc.toNsResource(property, conf)); + p.setProperty(property); + if (ontoBean != null) { + p.setLabel(ontoBean.getEscapedValue("label", locale, property)); + p.setComment(ontoBean.getEscapedValue("comment", locale, property)); + } + p.setPropertyUrl(Misc.toBrowsableUrl(property, conf)); + rb.setProperty(p); + if (qs.get("o") != null) { + Node object = qs.get("o").asNode(); + if (object.isURI()) { + rb.setType("iri"); + rb.setValue(object.toString(false)); + } else if (object.isLiteral()) { + rb.setType("literal"); + rb.setDataType(object.getLiteralDatatypeURI()); + rb.setNsDataType(Misc.toNsResource(object.getLiteralDatatypeURI(), conf)); + rb.setLang(object.getLiteralLanguage()); + rb.setValue(object.getLiteralLexicalForm()); + } else if (object.isBlank()) { + rb.setType("bnode"); + rb.setValue(object.toString(false)); + } + } else { + rb.setType("literal"); + rb.setValue(""); + } + results.add(rb); + } catch (Exception e) { + logger.error("error? " + e.getMessage()); + // e.printStackTrace(); + } + } + } catch (Exception ez) { + if (retry < 3) { + retry++; + // logger.trace("query failed (" + ez.getMessage() + + // "), I'm giving another chance (" + retry + "/3)"); + return moreThenOneQuery(qe, results, retry, overrideProperty); + } + ez.printStackTrace(); + throw new Exception("connection refused"); + } + + return results; + } + + public List doQuery(String IRI, List queries, String overrideProperty) throws Exception { + return doQuery(IRI, null, -1, queries, null, overrideProperty); + } + + public List doLocalQuery(Model m, String IRI, List queries, String about) throws Exception { + return doLocalQuery(m, IRI, null, -1, queries, about); + } + + public List doLocalQuery(Model model, String IRI, List queries) throws Exception { + return doLocalQuery(model, IRI, null, -1, queries, null); + } + + public List doLocalQuery(Model model, String IRI, String localProperty, int start, List queries, String overrideProperty) throws Exception { + // logger.trace("executing query on model based on " + IRI); + List results = new ArrayList(); + + for (String query : queries) { + QueryExecution qe = QueryExecutionFactory.create(parseQuery(query, IRI, localProperty, start, null), model); + try { + ResultSet rs = qe.execSelect(); + while (rs.hasNext()) { + TripleBean rb = new TripleBean(); + QuerySolution qs = rs.next(); + String property = ""; + if (overrideProperty != null) { + property = overrideProperty; + } else if (qs.get("p") != null) { + property = qs.get("p").asNode().toString(); + } + try { + if (qs.get("s") != null && !qs.get("s").asNode().toString().startsWith("http://")) { // probably + // blanknode + rb.setIri(qs.get("s").asNode().toString()); + rb.setNsIri("_:" + rb.getIri()); + } else if (qs.get("s") != null && qs.get("s").asNode().toString().startsWith("http://")) { + rb.setIri(qs.get("s").asNode().toString()); + rb.setNsIri(Misc.toNsResource(rb.getIri(), conf)); + rb.setUrl(Misc.toBrowsableUrl(rb.getIri(), conf)); + } + PropertyBean p = new PropertyBean(); + p.setNsProperty(Misc.toNsResource(property, conf)); + p.setProperty(property); + p.setPropertyUrl(Misc.toBrowsableUrl(property, conf)); + if (ontoBean != null) { + p.setLabel(ontoBean.getEscapedValue("label", locale, property)); + p.setComment(ontoBean.getEscapedValue("comment", locale, property)); + } + rb.setProperty(p); + if (qs.get("o") != null) { + Node object = qs.get("o").asNode(); + if (object.isURI()) { + rb.setType("iri"); + rb.setValue(object.toString(false)); + } else if (object.isLiteral()) { + rb.setType("literal"); + rb.setDataType(object.getLiteralDatatypeURI()); + rb.setNsDataType(Misc.toNsResource(object.getLiteralDatatypeURI(), conf)); + rb.setLang(object.getLiteralLanguage()); + rb.setValue(object.getLiteralLexicalForm()); + } else if (object.isBlank()) { + rb.setType("bnode"); + rb.setValue(object.toString(false)); + } + } else { + rb.setType("literal"); + rb.setValue(""); + } + results.add(rb); + } catch (Exception e) { + logger.error("error? " + e.getMessage()); + e.printStackTrace(); + } + } + } catch (Exception e) { + throw new Exception("500 - " + e.getMessage()); + } finally { + qe.close(); + } + } + + if (results.size() == 0) { + throw new Exception("404 - not found"); + } + return results; + } + + public Model extractData(Model result, String IRI, String sparql, List queries) throws Exception { + + // logger.trace("executing query on " + sparql); + Resource subject = result.createResource(IRI); + for (String query : queries) { + QueryExecution qe = QueryExecutionFactory.sparqlService(sparql, parseQuery(query, IRI, null, -1, null)); + try { + ResultSet rs = qe.execSelect(); + + List sl = new ArrayList(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + RDFNode subject2 = qs.get("s"); + RDFNode property = qs.get("p"); + RDFNode object = qs.get("o"); + Property property1 = result.createProperty(property.asNode().toString()); + result.add(result.createStatement(subject2 != null ? subject2.asResource() : subject, property1, object)); + } + result.add(sl); + } catch (Exception e) { + e.printStackTrace(); + throw new Exception("error in query execution: " + e.getMessage()); + } finally { + qe.close(); + } + } + return result; + } + + public Model extractLocalData(Model result, String IRI, Model m, List queries) throws Exception { + + // logger.trace("executing query on IRI"); + Resource subject = result.createResource(IRI); + for (String query : queries) { + QueryExecution qe = QueryExecutionFactory.create(parseQuery(query, IRI, null, -1, null), m); + try { + ResultSet rs = qe.execSelect(); + List sl = new ArrayList(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + RDFNode subject2 = qs.get("s"); + RDFNode property = qs.get("p"); + RDFNode object = qs.get("o"); + Property property1 = result.createProperty(property.asNode().toString()); + result.add(result.createStatement(subject2 != null ? subject2.asResource() : subject, property1, object)); + } + result.add(sl); + } catch (Exception e) { + e.printStackTrace(); + throw new Exception("error in query execution: " + e.getMessage()); + } finally { + qe.close(); + } + } + return result; + } + + public String parseQuery(String query, String IRI, String property, int start, String filter) { + if (IRI != null) { + /* managing issues depending on "$" in some IRIs */ + query = query.replaceAll("\\$\\{IRI\\}", IRI.replaceAll("\\$", "%24")).replaceAll("%24", "\\$"); + } + if (property != null) { + query = query.replaceAll("\\$\\{PROPERTY\\}", property); + } + if (filter != null) { + query = query.replaceAll("\\$\\{FILTERPROPERTY\\}", filter); + } + if (query.indexOf("STARTFROM") > 0) { + query = query.replaceAll("\\$\\{STARTFROM\\}", "" + start); + } else if (start > 0) { + query = query.replaceAll("LIMIT (.+)$", "OFFSET " + start + " LIMIT $1"); + } + return query; + } + + public String testEndpoint(ConfigurationBean conf) { + logger.info("testing connection on " + conf.getEndPointUrl()); + QueryExecution qe = QueryExecutionFactory.sparqlService(conf.getEndPointUrl(), "select ?s {?s ?p ?o} LIMIT 1"); + String msg = ""; + try { + ResultSet rs = qe.execSelect(); + if (rs.hasNext()) { + logger.info("is online"); + msg = "online"; + } else { + logger.info("is offline"); + msg = "offline"; + } + } catch (Exception e) { + logger.info("is offline " + e.getMessage()); + msg = "offline " + e.getMessage(); + } finally { + qe.close(); + } + return msg; + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/utils/Misc.java b/src/main/java/it/gov/innovazione/lodviewng/utils/Misc.java new file mode 100644 index 0000000..8a8ca5e --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/utils/Misc.java @@ -0,0 +1,143 @@ +package it.gov.innovazione.lodviewng.utils; + + +import it.gov.innovazione.lodviewng.bean.OntologyBean; +import it.gov.innovazione.lodviewng.bean.PropertyBean; +import it.gov.innovazione.lodviewng.bean.TripleBean; +import it.gov.innovazione.lodviewng.bean.ResultBean; +import it.gov.innovazione.lodviewng.conf.ConfigurationBean; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.NodeIterator; +import org.apache.jena.rdf.model.RDFNode; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@Slf4j +public class Misc { + + public static String toNsResource(String iri, ConfigurationBean conf) { + if (iri != null && !iri.equals("")) { + return conf.getNsURIPrefix(iri.replaceAll("[^/#]+$", "")) + ":" + iri.replaceAll(".+[/|#]([^/#]+)$", "$1"); + + } else { + return null; + } + } + + public static String toBrowsableUrl(String value, ConfigurationBean conf) { + + if (!conf.getPublicUrlSuffix().equals("") && value.startsWith(conf.getIRInamespace())) { + return conf.getPublicUrlPrefix() + "?" + conf.getPublicUrlSuffix() + "IRI=" + java.net.URLEncoder.encode(value, StandardCharsets.UTF_8); + } else { + return value + .replaceAll("^" + conf.getIRInamespace() + "(.+)$", conf.getPublicUrlPrefix() + "$1") + .replaceAll("([^:])//", "$1/") + .replaceAll("^//", "/"); + } + } + + public static String guessColor(String colorPair, ResultBean r, ConfigurationBean conf) { + switch (conf.getColorStrategy()) { + case CLASS: { + try { + List m = r.getResources(r.getMainIRI()).get(r.getTypeProperty()); + for (TripleBean tripleBean : m) { + colorPair = conf.getColorPairMatcher().get(tripleBean.getValue()); + if (colorPair != null) return colorPair; + } + } catch (Exception e) { + } + return conf.getColorPairMatcher().get("http://lodview.it/conf#otherClasses"); + } + case PREFIX: { + for (String prefix : conf.getColorPairMatcher().keySet()) { + if (r.getMainIRI().startsWith(prefix)) { + return conf.getColorPairMatcher().get(prefix); + } + } + break; + } + default: + break; + } + return colorPair; + } + + public static ResultBean guessClass(ResultBean r, ConfigurationBean conf, OntologyBean ontoBean) { + try { + if (!conf.getMainOntologiesPrefixes().isEmpty()) { + String mainIri = r.getMainIRI(); + Map> mainResource = r.getResources(mainIri); + TreeMap> resultOrderedMap = new TreeMap<>(); + + List m = new ArrayList<>(mainResource.get(r.getTypeProperty())); + Model model = ontoBean.getModel(); + for (TripleBean tripleBean : m) { + int dept = 0; + if (startsWithAtLeastOne(tripleBean.getValue(), conf.getMainOntologiesPrefixes())) { + dept = countFathers(tripleBean.getValue(), 0, model); + } + List l = null; + if (resultOrderedMap.get(dept) != null) { + l = resultOrderedMap.get(dept); + } else { + l = new ArrayList<>(); + } + l.add(tripleBean); + resultOrderedMap.put(dept, l); + // removing types + r.removeResource(tripleBean, mainIri); + } + if (resultOrderedMap.size() > 0) { + for (Integer dept : resultOrderedMap.descendingKeySet()) { + List l = resultOrderedMap.get(dept); + for (TripleBean tripleBean : l) { + // adding ordered types + r.addResource(tripleBean, mainIri); + } + } + } + } + return r; + } catch (RuntimeException re) { + throw re; + } catch (Exception e) { + log.warn("Unable to guess class: " + e); + } + return r; + } + + private static Integer countFathers(String value, int i, Model model) { + NodeIterator iter = model.listObjectsOfProperty(model.createResource(value), model.createProperty("http://www.w3.org/2000/01/rdf-schema#subClassOf")); + while (iter.hasNext()) { + RDFNode node = iter.next(); + return countFathers(node.toString(), ++i, model); + } + return i; + } + + private static boolean startsWithAtLeastOne(String value, List startsWithList) { + for (String string : startsWithList) { + if (value.startsWith(string)) { + return true; + } + } + return false; + } + + public static String stripHTML(String value) { + + value = value.replaceAll("]*>", ""); + + return value; + } + +} diff --git a/src/main/java/it/gov/innovazione/lodviewng/utils/ResourceClassPathLoader.java b/src/main/java/it/gov/innovazione/lodviewng/utils/ResourceClassPathLoader.java new file mode 100644 index 0000000..9f89a01 --- /dev/null +++ b/src/main/java/it/gov/innovazione/lodviewng/utils/ResourceClassPathLoader.java @@ -0,0 +1,47 @@ +package it.gov.innovazione.lodviewng.utils; + + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.SneakyThrows; +import org.apache.commons.io.FileUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; + +import java.io.File; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ResourceClassPathLoader { + + @SneakyThrows + public static File toFile(@NonNull Resource resource) { + String fileExtension = Optional.of(resource) + .map(Resource::getFilename) + .map(s -> s.substring(s.lastIndexOf("."))) + .orElse(""); + InputStream initialStream = resource.getInputStream(); + File tempFileName = File.createTempFile("lodview", fileExtension); + FileUtils.copyInputStreamToFile(initialStream, tempFileName); + return tempFileName; + } + + public static File toFile(String resource) { + return toFile(new ClassPathResource(resource)); + } + + @SneakyThrows + public static List toFiles(String directory) { + PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); + Resource[] resources = pathMatchingResourcePatternResolver.getResources("classpath*:" + directory + "/*"); + return Arrays.stream(resources) + .map(ResourceClassPathLoader::toFile) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/org/dvcama/lodview/bean/OntologyBean.java b/src/main/java/org/dvcama/lodview/bean/OntologyBean.java deleted file mode 100644 index f0eff64..0000000 --- a/src/main/java/org/dvcama/lodview/bean/OntologyBean.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.dvcama.lodview.bean; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import javax.servlet.ServletContext; - -import org.apache.commons.lang3.StringEscapeUtils; -import org.springframework.web.context.ServletContextAware; - -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.NodeIterator; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.util.FileManager; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class OntologyBean implements ServletContextAware { - - private String ontoDir; - private ServletContext context; - private Model model; - final Logger logger = LoggerFactory.getLogger(OntologyBean.class); - - public void init() { - File ontoDirFile = new File(ontoDir); - if (!ontoDirFile.isAbsolute()) { - ontoDirFile = new File(context.getRealPath("/") + "/WEB-INF/" + ontoDir); - } - model = ModelFactory.createDefaultModel(); - if (ontoDirFile.exists()) { - logger.debug("ontologies dir founded!"); - File[] list = ontoDirFile.listFiles(); - for (File file : list) { - if (!file.isDirectory()) { - try { - logger.debug("loading " + file.getCanonicalPath()); - FileManager.get().readModel(model, file.getAbsolutePath()); - logger.debug("read successfully!"); - } catch (Exception e) { - logger.error("error loading " + e.getMessage()); - // e.printStackTrace(); - } - } - } - } else { - logger.debug("no ontologies founded " + ontoDirFile.getAbsolutePath()); - } - - // logger.debug("------------------- " + getHashResult("en", - // "http://dati.camera.it/ocd/parentCountry")); - // logger.debug("------------------- " + getHashResult("it", - // "http://dati.camera.it/ocd/parentCountry")); - - } - - @Override - public void setServletContext(ServletContext arg0) { - this.context = arg0; - try { - init(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - public String getOntoDir() { - return ontoDir; - } - - public void setOntoDir(String ontoDir) { - this.ontoDir = ontoDir; - } - - public String getValue(String what, String preferredLanguage, String IRI) { - Resource IRIresource = model.createResource(IRI); - return getSingleValue(preferredLanguage, IRIresource, "http://www.w3.org/2000/01/rdf-schema#" + what, ""); - } - - public String getEscapedValue(String what, String preferredLanguage, String IRI) { - return StringEscapeUtils.escapeHtml4(getValue(what, preferredLanguage, IRI)); - } - - public Map getHashResult(String preferredLanguage, String IRI) { - Map result = new HashMap(); - Resource IRIresource = model.createResource(IRI); - result.put("label", getSingleValue(preferredLanguage, IRIresource, "http://www.w3.org/2000/01/rdf-schema#label", "")); - result.put("comment", getSingleValue(preferredLanguage, IRIresource, "http://www.w3.org/2000/01/rdf-schema#comment", "")); - return result; - } - - private String getSingleValue(String preferredLanguage, Resource IRI, String prop, String defaultValue) { - NodeIterator iter = model.listObjectsOfProperty(IRI, model.createProperty(prop)); - String result = defaultValue; - boolean betterTitleMatch = false; - while (iter.hasNext()) { - RDFNode node = iter.nextNode(); - Literal l = node.asLiteral(); - //logger.debug(IRI + " " + preferredLanguage + " --> " + l.getLanguage() + " --> " + l.getLexicalForm()); - if (!betterTitleMatch && (result.equals(defaultValue) || l.getLanguage().equals("en") || l.getLanguage().equals(preferredLanguage))) { - if (preferredLanguage.equals(l.getLanguage())) { - betterTitleMatch = true; - } - result = l.getLexicalForm(); - } - - } - return result; - } - - public Model getModel() { - return model; - } - - public void setModel(Model model) { - this.model = model; - } - -} diff --git a/src/main/java/org/dvcama/lodview/bean/PropertyBean.java b/src/main/java/org/dvcama/lodview/bean/PropertyBean.java deleted file mode 100644 index 7de314a..0000000 --- a/src/main/java/org/dvcama/lodview/bean/PropertyBean.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.dvcama.lodview.bean; - -public class PropertyBean { - - private String nsProperty = null, property = null, propertyUrl = null; - private String label = ""; - private String comment = ""; - - public String getPropertyUrl() { - return propertyUrl; - } - - public void setPropertyUrl(String propertyUrl) { - this.propertyUrl = propertyUrl; - } - - public String getNsProperty() { - return nsProperty; - } - - public void setNsProperty(String nsProperty) { - this.nsProperty = nsProperty; - } - - public String getProperty() { - return property; - } - - public void setProperty(String property) { - this.property = property; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((nsProperty == null) ? 0 : nsProperty.hashCode()); - result = prime * result + ((property == null) ? 0 : property.hashCode()); - result = prime * result + ((propertyUrl == null) ? 0 : propertyUrl.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PropertyBean other = (PropertyBean) obj; - if (nsProperty == null) { - if (other.nsProperty != null) - return false; - } else if (!nsProperty.equals(other.nsProperty)) - return false; - if (property == null) { - if (other.property != null) - return false; - } else if (!property.equals(other.property)) - return false; - if (propertyUrl == null) { - if (other.propertyUrl != null) - return false; - } else if (!propertyUrl.equals(other.propertyUrl)) - return false; - return true; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - -} diff --git a/src/main/java/org/dvcama/lodview/bean/ResultBean.java b/src/main/java/org/dvcama/lodview/bean/ResultBean.java deleted file mode 100644 index 20b36dc..0000000 --- a/src/main/java/org/dvcama/lodview/bean/ResultBean.java +++ /dev/null @@ -1,198 +0,0 @@ -package org.dvcama.lodview.bean; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class ResultBean { - - private String title, latitude = null, longitude = null, mainIRI = null; - private PropertyBean descriptionProperty = null, typeProperty = null; - private List images = null, linking = null, videos = null, audios = null; - private Map>> literals = new HashMap>>(), resources = new HashMap>>(), bnodes = new HashMap>>(); - - private Map>> addEle(String IRI, TripleBean tripleBean, Map>> ele) { - if (ele.get(IRI) == null || ele.get(IRI).get(tripleBean.getProperty()) == null) { - LinkedHashMap> a = ele.get(IRI); - if (a == null) { - a = new LinkedHashMap>(); - } - List b = new ArrayList(); - b.add(tripleBean); - a.put(tripleBean.getProperty(), b); - ele.put(IRI, a); - } else { - LinkedHashMap> a = ele.get(IRI); - List b = a.get(tripleBean.getProperty()); - b.add(tripleBean); - a.put(tripleBean.getProperty(), b); - ele.put(IRI, a); - } - return ele; - } - - private Map>> removeEle(String IRI, TripleBean tripleBean, Map>> ele) { - if (ele.get(IRI) == null || ele.get(IRI).get(tripleBean.getProperty()) == null) { - - } else { - LinkedHashMap> a = ele.get(IRI); - List b = a.get(tripleBean.getProperty()); - b.remove(tripleBean); - a.put(tripleBean.getProperty(), b); - ele.put(IRI, a); - } - return ele; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public List getImages() { - return images; - } - - public void setImages(List images) { - this.images = images; - } - - public void setLiterals(String IRI, List localLiterals) { - for (TripleBean tripleBean : localLiterals) { - literals = addEle(IRI, tripleBean, literals); - } - - } - - public void setBnodes(String IRI, List localBnodes) { - for (TripleBean tripleBean : localBnodes) { - bnodes = addEle(IRI, tripleBean, bnodes); - } - - } - - public void setResources(String IRI, List Localresources) { - for (TripleBean tripleBean : Localresources) { - resources = addEle(IRI, tripleBean, resources); - } - - } - - public LinkedHashMap> getResources(String IRI) { - return resources.get(IRI); - } - - public LinkedHashMap> getLiterals(String IRI) { - return literals.get(IRI); - } - - public Map>> getLiterals() { - return literals; - } - public LinkedHashMap> getBnodes(String IRI) { - return bnodes.get(IRI); - } - - public String getLongitude() { - return longitude; - } - - public void setLongitude(String longitude) { - this.longitude = longitude; - } - - public String getLatitude() { - return latitude; - } - - public List getAudios() { - return audios; - } - - public List getVideos() { - return videos; - } - - public void setLatitude(String latitude) { - this.latitude = latitude; - } - - public List getLinking() { - return linking; - } - - public void setLinking(List linking) { - this.linking = linking; - } - - @Override - public String toString() { - return "ResultBean [title=" + title + ", \ndescriptionProperty=" + descriptionProperty + ", \nlatitude=" + latitude + ", \nlongitude=" + longitude + ", \nimages=" + images + ", \nlinking=" + linking + ", \nliterals=" + literals + ", \nresources=" + resources + ", \nbnodes=" + bnodes + "]"; - } - - public String getMainIRI() { - return mainIRI; - } - - public void setMainIRI(String mainIRI) { - this.mainIRI = mainIRI; - } - - public void addBnode(TripleBean tripleBean, String IRI) { - - bnodes = addEle(IRI, tripleBean, bnodes); - } - - public void addLiteral(TripleBean tripleBean, String IRI) { - literals = addEle(IRI, tripleBean, literals); - - } - - public void addResource(TripleBean tripleBean, String IRI) { - resources = addEle(IRI, tripleBean, resources); - } - - public void removeBnode(TripleBean tripleBean, String IRI) { - - bnodes = removeEle(IRI, tripleBean, bnodes); - } - - public void removeLiteral(TripleBean tripleBean, String IRI) { - literals = removeEle(IRI, tripleBean, literals); - - } - - public void removeResource(TripleBean tripleBean, String IRI) { - resources = removeEle(IRI, tripleBean, resources); - } - - public PropertyBean getDescriptionProperty() { - return descriptionProperty; - } - - public void setDescriptionProperty(PropertyBean descriptionProperty) { - this.descriptionProperty = descriptionProperty; - } - - public PropertyBean getTypeProperty() { - return typeProperty; - } - - public void setTypeProperty(PropertyBean typeProperty) { - this.typeProperty = typeProperty; - } - - public void setVideos(List videos) { - this.videos = videos; - } - - public void setAudios(List audios) { - this.audios = audios; - } - -} diff --git a/src/main/java/org/dvcama/lodview/bean/TripleBean.java b/src/main/java/org/dvcama/lodview/bean/TripleBean.java deleted file mode 100644 index 53bae1a..0000000 --- a/src/main/java/org/dvcama/lodview/bean/TripleBean.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.dvcama.lodview.bean; - - -public class TripleBean { - private String nsValue = null, type = null, IRI = null, nsIRI = null, value = null, dataType = null, nsDataType = null, lang = null, url = null; - private boolean isLocal = false; - PropertyBean property = null; - - public PropertyBean getProperty() { - return property; - } - - public void setProperty(PropertyBean property) { - this.property = property; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public String getNsValue() { - return nsValue; - } - - public void setValue(String value) { - this.value = value; - } - - public void setNsValue(String nsValue) { - this.nsValue = nsValue; - } - - public String getLang() { - return lang; - } - - public void setLang(String lang) { - this.lang = lang; - } - - public String getDataType() { - return dataType; - } - - public void setDataType(String dataType) { - this.dataType = dataType; - } - - @Override - public String toString() { - return "TripleBean [property=" + property + ", nsValue=" + nsValue + ", type=" + type + ", IRI=" + IRI + ", nsIRI=" + nsIRI + ", value=" + value + ", dataType=" + dataType + ", nsDataType=" + nsDataType + ", lang=" + lang + ", url=" + url + ", isLocal=" + isLocal + "]"; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public boolean isLocal() { - return isLocal; - } - - public void setLocal(boolean isLocal) { - this.isLocal = isLocal; - } - - public String getIRI() { - return IRI; - } - - public void setIRI(String iRI) { - IRI = iRI; - } - - public String getNsDataType() { - return nsDataType; - } - - public void setNsDataType(String nsDataType) { - this.nsDataType = nsDataType; - } - - public String getNsIRI() { - return nsIRI; - } - - public void setNsIRI(String nsIRI) { - this.nsIRI = nsIRI; - } -} diff --git a/src/main/java/org/dvcama/lodview/builder/ResourceBuilder.java b/src/main/java/org/dvcama/lodview/builder/ResourceBuilder.java deleted file mode 100644 index e5de9d3..0000000 --- a/src/main/java/org/dvcama/lodview/builder/ResourceBuilder.java +++ /dev/null @@ -1,330 +0,0 @@ -package org.dvcama.lodview.builder; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.apache.jena.riot.Lang; -import org.dvcama.lodview.bean.OntologyBean; -import org.dvcama.lodview.bean.ResultBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.dvcama.lodview.endpoint.SPARQLEndPoint; -import org.dvcama.lodview.utils.Misc; -import org.springframework.context.MessageSource; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.ModelFactory; -import com.hp.hpl.jena.rdf.model.RDFWriter; - -public class ResourceBuilder { - - private MessageSource messageSource; - - public ResourceBuilder() { - } - - public ResourceBuilder(MessageSource messageSource) { - this.messageSource = messageSource; - } - - public ResultBean buildHtmlResource(String IRI, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { - return buildHtmlResource(IRI, locale, conf, ontoBean, false); - } - - public ResultBean buildHtmlResource(String IRI, Locale locale, ConfigurationBean conf, OntologyBean ontoBean, boolean localMode) throws Exception { - ResultBean result = new ResultBean(); - List videos = new ArrayList(); - List audios = new ArrayList(); - List images = new ArrayList(); - List linking = new ArrayList(); - SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); - result.setMainIRI(IRI); - - String preferredLanguage = conf.getPreferredLanguage(); - if (preferredLanguage.equals("auto")) { - preferredLanguage = locale.getLanguage(); - } - List triples = new ArrayList(); - if (conf.getEndPointUrl() != null && conf.getEndPointUrl().equals("<>")) { - localMode = true; - } - if (localMode) { - /* looking for data via content negotiation */ - Model m = ModelFactory.createDefaultModel(); - try { - m.read(IRI); - } catch (Exception e) { - throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", locale)); - } - triples = se.doLocalQuery(m, IRI, conf.getDefaultQueries()); - } else { - triples = se.doQuery(IRI, conf.getDefaultQueries(), null); - } - boolean betterTitleMatch = false, betterDescrMatch = false; - for (TripleBean tripleBean : triples) { - - if (tripleBean.getIRI() == null) { - tripleBean.setIRI(IRI); - tripleBean.setNsIRI(Misc.toNsResource(tripleBean.getIRI(), conf)); - } - - if (conf.getTitleProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getTitleProperties().contains(tripleBean.getProperty().getProperty())) { - if (tripleBean.getIRI().equals(IRI) && !betterTitleMatch && (result.getTitle() == null || result.getTitle().trim().equals("") || (tripleBean.getLang() != null && (preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))))) { - result.setTitle(Misc.stripHTML(tripleBean.getValue())); - if (preferredLanguage.equals(tripleBean.getLang())) { - betterTitleMatch = true; - } - } - } else if (conf.getDescriptionProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getDescriptionProperties().contains(tripleBean.getProperty().getProperty())) { - if (tripleBean.getIRI().equals(IRI) && !betterDescrMatch && (result.getDescriptionProperty() == null || (tripleBean.getLang() != null && (preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))))) { - result.setDescriptionProperty(tripleBean.getProperty()); - if (preferredLanguage.equals(tripleBean.getLang())) { - betterDescrMatch = true; - } - } - } else if (conf.getLatitudeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLatitudeProperties().contains(tripleBean.getProperty().getProperty())) { - result.setLatitude(tripleBean.getValue()); - } else if (conf.getLongitudeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLongitudeProperties().contains(tripleBean.getProperty().getProperty())) { - result.setLongitude(tripleBean.getValue()); - } else if (conf.getImageProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getImageProperties().contains(tripleBean.getProperty().getProperty())) { - images.add(tripleBean.getValue()); - } else if (conf.getAudioProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getAudioProperties().contains(tripleBean.getProperty().getProperty())) { - audios.add(tripleBean.getValue()); - } else if (conf.getVideoProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getVideoProperties().contains(tripleBean.getProperty().getProperty())) { - videos.add(tripleBean.getValue()); - } else if (conf.getLinkingProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getLinkingProperties().contains(tripleBean.getProperty().getProperty())) { - linking.add(tripleBean.getValue()); - } else if (conf.getTypeProperties().contains(tripleBean.getProperty().getNsProperty()) || conf.getTypeProperties().contains(tripleBean.getProperty().getProperty())) { - result.setTypeProperty(tripleBean.getProperty()); - } - - if (tripleBean.getType().equals("iri")) { - tripleBean.setUrl(Misc.toBrowsableUrl(tripleBean.getValue(), conf)); - tripleBean.setNsValue(Misc.toNsResource(tripleBean.getValue(), conf)); - if (!tripleBean.getUrl().equals(tripleBean.getValue()) || tripleBean.getValue().startsWith(conf.getPublicUrlPrefix())) { - tripleBean.setLocal(true); - } - result.addResource(tripleBean, tripleBean.getIRI()); - } else if (tripleBean.getType().equals("literal")) { - result.addLiteral(tripleBean, tripleBean.getIRI()); - } else if (tripleBean.getType().equals("bnode")) { - result.addBnode(tripleBean, tripleBean.getIRI()); - } - } - - result.setImages(images); - result.setLinking(linking); - result.setVideos(videos); - result.setAudios(audios); - - return result; - } - - public String buildRDFResource(String IRI, String sparql, Lang lang, ConfigurationBean conf) throws Exception { - String result = "empty content"; - Model model = ModelFactory.createDefaultModel(); - model.setNsPrefixes(conf.getPrefixes()); - - SPARQLEndPoint se = new SPARQLEndPoint(conf, null, null); - model = se.extractData(model, IRI, sparql, conf.getDefaultRawDataQueries()); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - RDFWriter rdfWriter = model.getWriter(lang.getName()); - rdfWriter.setProperty("showXMLDeclaration","true"); - rdfWriter.setProperty("relativeURIs",""); - - rdfWriter.write(model, baos, conf.getIRInamespace()); - - byte[] resultByteArray = baos.toByteArray(); - result = new String(resultByteArray); - - return result; - } - - public String buildRDFResource(String IRI, Model m, Lang lang, ConfigurationBean conf) throws Exception { - String result = "empty content"; - Model model = ModelFactory.createDefaultModel(); - model.setNsPrefixes(conf.getPrefixes()); - - SPARQLEndPoint se = new SPARQLEndPoint(conf, null, null); - model = se.extractLocalData(model, IRI, m, conf.getDefaultRawDataQueries()); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - RDFWriter rdfWriter = model.getWriter(lang.getName()); - rdfWriter.setProperty("showXMLDeclaration","true"); - rdfWriter.setProperty("relativeURIs",""); - - rdfWriter.write(model, baos, conf.getIRInamespace()); - rdfWriter.setProperty("showXMLDeclaration","true"); - rdfWriter.setProperty("relativeURIs",""); - - byte[] resultByteArray = baos.toByteArray(); - result = new String(resultByteArray); - - return result; - } - - public ResultBean buildPartialHtmlResource(String IRI, String[] abouts, Locale locale, ConfigurationBean conf, OntologyBean ontoBean, List filterProperties) throws Exception { - - SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); - ResultBean result = new ResultBean(); - List literals = new ArrayList(); - - String preferredLanguage = conf.getPreferredLanguage(); - if (preferredLanguage.equals("auto")) { - preferredLanguage = locale.getLanguage(); - } - - List triples = new ArrayList(); - - /* - * FIXME: make more distinct queries to avoid length limits, eg - * http://dati.camera.it/ocd/assemblea.rdf/a16 - */ - - StringBuilder filter = new StringBuilder(); - for (String titleProperty : filterProperties) { - if (titleProperty.toLowerCase().startsWith("http:")) { - filter.append("(?filterProperty = <" + titleProperty + ">)"); - } else { - filter.append("(?filterProperty = " + titleProperty + ")"); - } - filter.append(" || "); - } - - for (String about : abouts) { - StringBuilder sparqlQuery = new StringBuilder("select distinct ?o "); - sparqlQuery.append("{ <" + about + "> ?filterProperty ?o. FILTER (" + filter + "))} "); - List sparqlQueries = new ArrayList(); - sparqlQueries.add(sparqlQuery.toString().replaceAll("\\|\\| \\)", "")); - try { - - if (conf.getEndPointUrl().equals("<>")) { - /* looking for data via content negotiation */ - Model m = ModelFactory.createDefaultModel(); - try { - m.read(about); - } catch (Exception e) { - throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", locale)); - } - triples.addAll(se.doLocalQuery(m, about, sparqlQueries, about)); - } else { - triples.addAll(se.doQuery(null, sparqlQueries, about)); - } - - } catch (Exception e) { - } - } - - Map> l = new HashMap>(); - - for (TripleBean tripleBean : triples) { - if (tripleBean.getType().equals("literal")) { - List al = l.get(tripleBean.getProperty().getProperty()); - if (al == null) { - al = new ArrayList(); - } - al.add(tripleBean); - l.put(tripleBean.getProperty().getProperty(), al); - } - } - for (String about : l.keySet()) { - List al = l.get(about); - boolean betterTitleMatch = false; - TripleBean title = null; - for (TripleBean tripleBean : al) { - if (!betterTitleMatch && (title == null || title.getValue() == null || title.getValue().trim().equals("") || preferredLanguage.equals(tripleBean.getLang()) || tripleBean.getLang().equals("en"))) { - title = tripleBean; - if (preferredLanguage.equals(tripleBean.getLang())) { - betterTitleMatch = true; - } - } - } - if (title != null) { - literals.add(title); - } - } - result.setLiterals(IRI, literals); - return result; - } - - public ResultBean buildHtmlInverseResource(String IRI, String property, int start, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { - ResultBean result = new ResultBean(); - - SPARQLEndPoint se = new SPARQLEndPoint(conf, ontoBean, locale.getLanguage()); - String preferredLanguage = conf.getPreferredLanguage(); - if (preferredLanguage.equals("auto")) { - preferredLanguage = locale.getLanguage(); - } - if (property == null) { - /* counting */ - List resources = new ArrayList(); - List triples = new ArrayList(); - - if (conf.getEndPointUrl().equals("<>")) { - /* looking for data via content negotiation */ - Model m = ModelFactory.createDefaultModel(); - try { - m.read(IRI); - } catch (Exception e) { - throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", locale)); - } - triples = se.doLocalQuery(m, IRI, conf.getDefaultInversesCountQueries()); - } else { - triples = se.doQuery(IRI, conf.getDefaultInversesCountQueries(), null); - } - - for (TripleBean tripleBean : triples) { - if (tripleBean.getType().equals("literal")) { - resources.add(tripleBean); - } - } - - result.setResources(IRI, resources); - - } else { - /* listing */ - List resources = new ArrayList(); - List triples = new ArrayList(); - - if (conf.getEndPointUrl().equals("<>")) { - /* looking for data via content negotiation */ - Model m = ModelFactory.createDefaultModel(); - try { - m.read(IRI); - } catch (Exception e) { - throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", locale)); - } - triples = se.doLocalQuery(m, IRI, property, start, conf.getDefaultInversesQueries(), null); - } else { - triples = se.doQuery(IRI, property, start, conf.getDefaultInversesQueries(), null, null); - } - - Map controlList = new HashMap(); - for (TripleBean tripleBean : triples) { - if (tripleBean.getType().equals("literal")) { - if (controlList.get(tripleBean.getProperty().getProperty()) == null || preferredLanguage.equals(tripleBean.getLang())) { - controlList.put(tripleBean.getProperty().getProperty(), tripleBean); - } - } - } - - for (String at : controlList.keySet()) { - resources.add(controlList.get(at)); - } - - result.setResources(IRI, resources); - - } - - return result; - } - - public ResultBean buildHtmlInverseResource(String IRI, Locale locale, ConfigurationBean conf, OntologyBean ontoBean) throws Exception { - return buildHtmlInverseResource(IRI, null, -1, locale, conf, ontoBean); - } -} diff --git a/src/main/java/org/dvcama/lodview/conf/ConfigurationBean.java b/src/main/java/org/dvcama/lodview/conf/ConfigurationBean.java deleted file mode 100644 index 87632c0..0000000 --- a/src/main/java/org/dvcama/lodview/conf/ConfigurationBean.java +++ /dev/null @@ -1,372 +0,0 @@ -package org.dvcama.lodview.conf; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import javax.servlet.ServletContext; - -import org.apache.jena.riot.RDFDataMgr; -import org.springframework.web.context.ServletContextAware; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.NodeIterator; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.ResIterator; -import com.hp.hpl.jena.rdf.model.Resource; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ConfigurationBean implements ServletContextAware, Cloneable { - - final Logger logger = LoggerFactory.getLogger(ConfigurationBean.class); - - protected Model confModel = null; - protected ServletContext context; - protected String confFile; - private String endPointType; - private String redirectionStrategy; - private String forceIriEncoding; - private String httpRedirectExcludeList; - private String homeUrl; - private String license; - private String httpRedirectSuffix; - private String httpRedirectPrefix; - private String endPointUrl; - private String IRInamespace; - private String contentEncoding; - private String staticResourceURL; - private String preferredLanguage; - private String publicUrlPrefix = null; - private String publicUrlSuffix = ""; - private String authUsername = null; - private String authPassword = null; - private String defaultInverseBehaviour = "collapse"; - - public enum ColorStrategy {RANDOM, CLASS, PREFIX} - private ColorStrategy colorStrategy = ColorStrategy.RANDOM; - public ColorStrategy getColorStrategy() {return colorStrategy;} - - private List defaultQueries = null, defaultRawDataQueries = null, defaultInversesQueries = null, defaultInversesTest = null, defaultInversesCountQueries = null, typeProperties = null, audioProperties = null, imageProperties = null, videoProperties = null, linkingProperties = null, titleProperties = null, descriptionProperties = null, longitudeProperties = null, latitudeProperties = null; - private List colorPair = null, skipDomains = null, mainOntologiesPrefixes = null; - private Map colorPairMatcher = null; - - Random rand = new Random(); - - public ConfigurationBean() throws IOException, Exception { - - } - - public void populateBean() throws IOException, Exception { - logger.debug("Initializing configuration " + confFile); - File configFile = new File(confFile); - if (!configFile.isAbsolute()) { - configFile = new File(context.getRealPath("/") + "/WEB-INF/" + confFile); - } - if (!configFile.exists()) { - throw new Exception("Configuration file not found (" + configFile.getAbsolutePath() + ")"); - } - confModel = RDFDataMgr.loadModel(configFile.getAbsolutePath()); - - endPointUrl = getSingleConfValue("endpoint"); - endPointType = getSingleConfValue("endpointType", ""); - authPassword = getSingleConfValue("authPassword"); - authUsername = getSingleConfValue("authUsername"); - forceIriEncoding = getSingleConfValue("forceIriEncoding", "auto"); - redirectionStrategy = getSingleConfValue("redirectionStrategy", ""); - - IRInamespace = getSingleConfValue("IRInamespace", ""); - - httpRedirectSuffix = getSingleConfValue("httpRedirectSuffix", ""); - httpRedirectPrefix = getSingleConfValue("httpRedirectPrefix", ""); - httpRedirectExcludeList = getSingleConfValue("httpRedirectExcludeList", ""); - - publicUrlPrefix = getSingleConfValue("publicUrlPrefix", ""); - publicUrlPrefix = publicUrlPrefix.replaceAll("^(.+/)?auto$", context.getContextPath() + "/"); - - contentEncoding = getSingleConfValue("contentEncoding"); - staticResourceURL = getSingleConfValue("staticResourceURL", ""); - homeUrl = getSingleConfValue("homeUrl", "/"); - staticResourceURL = staticResourceURL.replaceAll("^(.+/)?auto$", context.getContextPath() + "/staticResources/"); - - preferredLanguage = getSingleConfValue("preferredLanguage"); - - typeProperties = getMultiConfValue("typeProperties"); - titleProperties = getMultiConfValue("titleProperties"); - descriptionProperties = getMultiConfValue("descriptionProperties"); - imageProperties = getMultiConfValue("imageProperties"); - audioProperties = getMultiConfValue("audioProperties"); - videoProperties = getMultiConfValue("videoProperties"); - linkingProperties = getMultiConfValue("linkingProperties"); - longitudeProperties = getMultiConfValue("longitudeProperties"); - latitudeProperties = getMultiConfValue("latitudeProperties"); - - defaultQueries = getMultiConfValue("defaultQueries"); - defaultRawDataQueries = getMultiConfValue("defaultRawDataQueries"); - - defaultInversesQueries = getMultiConfValue("defaultInversesQueries"); - defaultInversesTest = getMultiConfValue("defaultInversesTest"); - defaultInversesCountQueries = getMultiConfValue("defaultInversesCountQueries"); - - defaultInverseBehaviour = getSingleConfValue("defaultInverseBehaviour", defaultInverseBehaviour); - mainOntologiesPrefixes = getMultiConfValue("mainOntologiesPrefixes"); - - license = getSingleConfValue("license", ""); - - colorPair = getMultiConfValue("colorPair"); - - if (colorPair != null && colorPair.size() == 1 && colorPair.get(0).startsWith("http://")) - { - switch(colorPair.get(0).replace("http://lodview.it/conf#", "")) - { - case "byClass": colorStrategy= ColorStrategy.CLASS; break; - case "byPrefix": colorStrategy= ColorStrategy.PREFIX; break; - } - colorPairMatcher = populateColorPairMatcher(); - } - - skipDomains = getMultiConfValue("skipDomains"); - } - - private Map populateColorPairMatcher() { - Map result = new HashMap(); - ResIterator iter = confModel.listSubjectsWithProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), "hasColorPair")); - while (iter.hasNext()) { - Resource res = iter.next(); - NodeIterator values = confModel.listObjectsOfProperty(res, confModel.createProperty(confModel.getNsPrefixURI("conf"), "hasColorPair")); - while (values.hasNext()) { - RDFNode node = values.next(); - result.put(res.toString(), node.toString()); - break; - } - } - return result; - } - - private String getSingleConfValue(String prop) { - return getSingleConfValue(prop, null); - } - - private String getSingleConfValue(String prop, String defaultValue) { - String value = System.getenv("LodView"+prop); - if(value!=null) {return value;} - NodeIterator iter = confModel.listObjectsOfProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), prop)); - while (iter.hasNext()) { - RDFNode node = iter.next(); - return node.toString(); - } - return defaultValue; - } - - private List getMultiConfValue(String prop) { - List result = new ArrayList(); - NodeIterator iter = confModel.listObjectsOfProperty(confModel.createProperty(confModel.getNsPrefixURI("conf"), prop)); - while (iter.hasNext()) { - RDFNode node = iter.next(); - result.add(node.toString()); - } - return result; - } - - @Override - public void setServletContext(ServletContext arg0) { - this.context = arg0; - try { - populateBean(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - public Model getConfModel() { - return confModel; - } - - public Map getPrefixes() { - return confModel.getNsPrefixMap(); - } - - public String getRedirectionStrategy() { - return redirectionStrategy; - } - - public String getPreferredLanguage() { - return preferredLanguage; - } - - public String getNsPrefixURI(String prefix) { - return confModel.getNsPrefixURI(prefix); - } - - public String getNsURIPrefix(String IRI) { - return confModel.getNsURIPrefix(IRI); - } - - public String getEndPointUrl() { - return endPointUrl; - } - - public List getDefaultQueries() { - return defaultQueries; - } - - public List getTypeProperties() { - return typeProperties; - } - - public String getIRInamespace() { - return IRInamespace; - } - - public String getPublicUrlPrefix() { - return publicUrlPrefix; - } - - public String getPublicUrlSuffix() { - return publicUrlSuffix; - } - - public List getDefaultRawDataQueries() { - return defaultRawDataQueries; - } - - public List getDefaultInversesQueries() { - return defaultInversesQueries; - } - - public List getDefaultInversesTest() { - return defaultInversesTest; - } - - public List getDefaultInversesCountQueries() { - return defaultInversesCountQueries; - } - - public String getStaticResourceURL() { - return staticResourceURL; - } - - public String getContentEncoding() { - return contentEncoding; - } - - public List getTitleProperties() { - return titleProperties; - } - - public List getLongitudeProperties() { - return longitudeProperties; - } - - public List getLatitudeProperties() { - return latitudeProperties; - } - - public List getDescriptionProperties() { - return descriptionProperties; - } - - public List getImageProperties() { - return imageProperties; - } - - public List getAudioProperties() { - return audioProperties; - } - - public List getVideoProperties() { - return videoProperties; - } - - public List getLinkingProperties() { - return linkingProperties; - } - - public String getLicense() { - return license; - } - - public List getColorPair() { - return colorPair; - } - - public String getRandomColorPair() { - if(colorStrategy!=ColorStrategy.RANDOM) {return "#914848-#7d3e3e";} - int randomNum = rand.nextInt(colorPair.size()); - return colorPair.get(randomNum); - } - - public List getSkipDomains() { - return skipDomains; - } - - public String getAuthPassword() { - return authPassword; - } - - public String getAuthUsername() { - return authUsername; - } - - public String getDefaultInverseBehaviour() { - return defaultInverseBehaviour; - } - - public Map getColorPairMatcher() { - return colorPairMatcher; - } - - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException e) { - throw new Error("Something impossible just happened"); - } - } - - @Override - public String toString() { - return "ConfigurationBean [confModel=" + confModel + ", context=" + context + ", confFile=" + confFile + ", endPointUrl=" + endPointUrl + ", IRInamespace=" + IRInamespace + ", contentEncoding=" + contentEncoding + ", staticResourceURL=" + staticResourceURL + ", preferredLanguage=" + preferredLanguage + ", publicUrlPrefix=" + publicUrlPrefix + ", authUsername=" + authUsername + ", authPassword=" + authPassword + ", defaultInverseBehaviour=" + defaultInverseBehaviour + ", defaultQueries=" + defaultQueries + ", defaultRawDataQueries=" + defaultRawDataQueries + ", defaultInversesQueries=" + defaultInversesQueries + ", defaultInversesTest=" + defaultInversesTest + ", defaultInversesCountQueries=" + defaultInversesCountQueries + ", typeProperties=" + typeProperties - + ", imageProperties=" + imageProperties + ", audioProperties=" + audioProperties + ", videoProperties=" + videoProperties + ", linkingProperties=" + linkingProperties + ", titleProperties=" + titleProperties + ", descriptionProperties=" + descriptionProperties + ", longitudeProperties=" + longitudeProperties + ", latitudeProperties=" + latitudeProperties + ", colorPair=" + colorPair + ", skipDomains=" + skipDomains + ", rand=" + rand + "]"; - } - - public String getHomeUrl() { - return homeUrl; - } - - public String getHttpRedirectSuffix() { - return httpRedirectSuffix; - } - - public String getHttpRedirectPrefix() { - return httpRedirectPrefix; - } - - public String getHttpRedirectExcludeList() { - return httpRedirectExcludeList; - } - - public List getMainOntologiesPrefixes() { - return mainOntologiesPrefixes; - } - - public String getForceIriEncoding() { - return forceIriEncoding; - } - - public String getEndPointType() { - return endPointType; - } - - public void setConfFile(String confFile) { - this.confFile = confFile; - } - -} diff --git a/src/main/java/org/dvcama/lodview/controllers/ErrorController.java b/src/main/java/org/dvcama/lodview/controllers/ErrorController.java deleted file mode 100644 index 69d944f..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/ErrorController.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.dvcama.lodview.controllers; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletResponse; - -import org.dvcama.lodview.conf.ConfigurationBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Controller -public class ErrorController { - - final Logger logger = LoggerFactory.getLogger(ErrorController.class); - - @Autowired - ConfigurationBean conf; - - public ErrorController(ConfigurationBean conf) { - this.conf = conf; - } - - public ErrorController() { - } - - /* TODO: change the handler to send "error" param to the client */ - @ResponseStatus(value = HttpStatus.NOT_ACCEPTABLE, reason = "unhandled encoding") - @RequestMapping(value = "/406") - public String error406(HttpServletResponse res, ModelMap model, @CookieValue(value = "colorPair") String colorPair) { - logger.error("not acceptable"); - model.addAttribute("statusCode", "406"); - model.addAttribute("conf", conf); - colors(colorPair, res, model); - res.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); - return "error"; - } - - @RequestMapping(value = "/404") - public String error404(HttpServletResponse res, ModelMap model, @RequestParam(value = "error", defaultValue = "") String error, @CookieValue(value = "colorPair", defaultValue = "") String colorPair, @RequestParam(value = "IRI", defaultValue = "") String IRI, @RequestParam(value = "endpoint", defaultValue = "") String endpoint) { - logger.error("not found " + error + " -- " + IRI + " -- " + endpoint); - /* spring bug? */ - model.addAttribute("IRI", IRI); - model.addAttribute("endpoint", endpoint); - model.addAttribute("error", error); - model.addAttribute("conf", conf); - colors(colorPair, res, model); - model.addAttribute("statusCode", "404"); - res.setStatus(HttpServletResponse.SC_NOT_FOUND); - return "error"; - } - - @RequestMapping(value = "/400") - public String error400(HttpServletResponse res, ModelMap model, @RequestParam(value = "IRI", defaultValue = "") String IRI, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) { - logger.error("error on " + IRI); - /* spring bug? */ - model.addAttribute("IRI", IRI.replaceAll("(http://.+),http://.+", "$1")); - model.addAttribute("conf", conf); - colors(colorPair, res, model); - model.addAttribute("statusCode", "400"); - res.setStatus(HttpServletResponse.SC_NOT_ACCEPTABLE); - return "error"; - } - - @RequestMapping(value = { "/500", "/error" }) - public String error500(HttpServletResponse res, ModelMap model, @RequestParam(value = "error", defaultValue = "") String error, @CookieValue(value = "colorPair", defaultValue = "") String colorPair, @RequestParam(value = "IRI", defaultValue = "") String IRI, @RequestParam(value = "endpoint", defaultValue = "") String endpoint) { - logger.error("error on " + error + " -- " + IRI + " -- " + endpoint); - /* spring bug? */ - model.addAttribute("IRI", IRI); - model.addAttribute("endpoint", endpoint); - model.addAttribute("error", error); - model.addAttribute("conf", conf); - colors(colorPair, res, model); - model.addAttribute("statusCode", "500"); - res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - return "error"; - } - - private void colors(String colorPair, HttpServletResponse res, ModelMap model) { - if (colorPair.equals("")) { - colorPair = conf.getRandomColorPair(); - Cookie c = new Cookie("colorPair", colorPair); - c.setPath("/"); - res.addCookie(c); - } - if (conf != null && conf.getColorPairMatcher() != null && conf.getColorPairMatcher().size() > 0) { - model.addAttribute("colorPair", conf.getColorPairMatcher().get("http://lodview.it/conf#otherClasses")); - } else { - model.addAttribute("colorPair", colorPair); - } - - } -} diff --git a/src/main/java/org/dvcama/lodview/controllers/LinkedResourcesController.java b/src/main/java/org/dvcama/lodview/controllers/LinkedResourcesController.java deleted file mode 100644 index de3c819..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/LinkedResourcesController.java +++ /dev/null @@ -1,154 +0,0 @@ -package org.dvcama.lodview.controllers; - -import java.io.IOException; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringEscapeUtils; -import org.dvcama.lodview.bean.OntologyBean; -import org.dvcama.lodview.bean.PropertyBean; -import org.dvcama.lodview.bean.ResultBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.builder.ResourceBuilder; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.dvcama.lodview.utils.Misc; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.context.MessageSourceAware; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Controller -public class LinkedResourcesController implements MessageSourceAware { - - final Logger logger = LoggerFactory.getLogger(LinkedResourcesController.class); - - @Autowired - private MessageSource messageSource; - - @Autowired - ConfigurationBean conf; - - @Autowired - OntologyBean ontoBean; - - public LinkedResourcesController() { - } - - public LinkedResourcesController(MessageSource messageSource) { - this.messageSource = messageSource; - } - - @ResponseBody - @RequestMapping(value = "/linkedResourceTitles", produces = "application/xml;charset=UTF-8") - public String resourceTitles(ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "abouts[]") String[] abouts) throws IOException, Exception { - return resourceTitles(model, conf, req, res, locale, IRI, abouts); - } - - public String resourceTitles(ModelMap model, ConfigurationBean conf, HttpServletRequest req, HttpServletResponse res, Locale locale, String IRI, String[] abouts) throws IOException, Exception { - // logger.trace("LinkedResourcesController.resourceTitles() locale: " - // + locale.getLanguage()); - StringBuilder result = new StringBuilder("\n"); - try { - ResultBean results = new ResourceBuilder(messageSource).buildPartialHtmlResource(IRI, abouts, locale, conf, null, conf.getTitleProperties()); - Map> literals = results.getLiterals(IRI); - if (literals == null || literals.size() == 0) { - return ("" + messageSource.getMessage("error.noLiteral", null, "no literal values where found", locale) + ""); - } - for (PropertyBean key : literals.keySet()) { - for (TripleBean tripleBean : literals.get(key)) { - result.append("<![CDATA[" + StringEscapeUtils.escapeHtml4(Misc.stripHTML(tripleBean.getValue())) + // - "]]>\n"); - } - } - result.append(""); - return result.toString(); - } catch (Exception e) { - // 404? - return ("" + messageSource.getMessage("error.linkedResourceUnavailable", null, "unable to retrieve data", locale) + "" + e.getMessage() + ""); - } - } - - @ResponseBody - @RequestMapping(value = "/linkedResourceInverses", produces = "application/xml;charset=UTF-8") - public String resourceInversesController(ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "property", defaultValue = "") String property, @RequestParam(value = "start", defaultValue = "-1") int start) throws IOException, Exception { - return resourceInverses(model, conf, ontoBean, req, res, locale, IRI, property, start); - } - - public String resourceInverses(ModelMap model, ConfigurationBean conf, OntologyBean ontoBean, HttpServletRequest req, HttpServletResponse res, Locale locale, String IRI, String property, int start) throws IOException, Exception { - StringBuilder result = new StringBuilder("\n"); - // logger.trace("LinkedResourcesController.resourceInverses()"); - if (property.equals("")) { - /* counting inverse relations */ - try { - - ResultBean results = new ResourceBuilder(messageSource).buildHtmlInverseResource(IRI, locale, conf, ontoBean); - Map> resources = results.getResources(IRI); - if (resources != null) { - for (PropertyBean key : resources.keySet()) { - for (TripleBean tripleBean : resources.get(key)) { - if (tripleBean.getProperty().getProperty() == null || tripleBean.getProperty().getProperty().equals("")) { - throw new Exception("no content"); - } - result.append("\n"); - } - } - } - - result.append(""); - return result.toString(); - - } catch (Exception e) { - // e.printStackTrace(); - return ("" + messageSource.getMessage("error.linkedResourceUnavailable", null, "unable to retrieve data", locale) + "" + e.getMessage() + ""); - } - } else { - - /* retrieving inverse relations */ - try { - ResultBean results = new ResourceBuilder(messageSource).buildHtmlInverseResource(IRI, property, start, locale, conf, null); - Map> resources = results.getResources(IRI); - for (PropertyBean key : resources.keySet()) { - for (TripleBean tripleBean : resources.get(key)) { - result.append("\n"); - } - } - - result.append(""); - return result.toString(); - - } catch (Exception e) { - e.printStackTrace(); - return ("" + messageSource.getMessage("error.linkedResourceUnavailable", null, "unable to retrieve data", locale) + ""); - } - } - } - - @Override - public void setMessageSource(MessageSource arg0) { - // TODO Auto-generated method stub - - } -} diff --git a/src/main/java/org/dvcama/lodview/controllers/LodController.java b/src/main/java/org/dvcama/lodview/controllers/LodController.java deleted file mode 100644 index 7e3cc13..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/LodController.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.dvcama.lodview.controllers; - -import java.io.IOException; -import java.util.List; -import java.util.Locale; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringEscapeUtils; -import org.dvcama.lodview.bean.ResultBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.builder.ResourceBuilder; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Controller -public class LodController { - - final Logger logger = LoggerFactory.getLogger(LodController.class); - - @Autowired - ConfigurationBean confLinked; - - @Autowired - private MessageSource messageSource; - - - @ResponseBody - @RequestMapping(value = { "/linkedResource", "/lodview/linkedResource" }, produces = "application/xml;charset=UTF-8") - public String resource(HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI) throws IOException, Exception { - - if (confLinked.getSkipDomains().contains(IRI.replaceAll("http[s]*://([^/]+)/.*", "$1"))) { - // logger.info("LodController.resource() - skip - " + IRI); - return "" + // - StringEscapeUtils.escapeXml11(messageSource.getMessage("error.skipedDomain", null, "skiping this URI", locale)) + // - ""; - } - try { - logger.info(" LodController.resource() - load - " + IRI); - /* TODO: change this in UNION queries for better performance */ - ResultBean results = new ResourceBuilder(messageSource).buildHtmlResource(IRI, locale, confLinked, null, true); - - StringBuilder result = new StringBuilder("\n"); - - result.append("<![CDATA[" + StringEscapeUtils.escapeHtml4(results.getTitle()) + "]]>"); - - String lang = locale.getLanguage().toLowerCase(); - String descr = ""; - List descrProperties = results.getLiterals(IRI).get(results.getDescriptionProperty()); - if (descrProperties != null) { - for (TripleBean tripleBean : descrProperties) { - if (lang.equals(tripleBean.getLang())) { - descr = tripleBean.getValue(); - lang = tripleBean.getLang(); - break; - } else if (tripleBean.getLang().equals("en")) { - lang = tripleBean.getLang(); - descr = tripleBean.getValue(); - } else if (descr.equals("")) { - descr = tripleBean.getValue(); - lang = tripleBean.getLang(); - } - } - } - /* - * List descrProperties = - * results.getLiterals(IRI).get(results.getDescriptionProperty()); - * if (descrProperties != null) { boolean betterDescrMatch = false; - * for (TripleBean tripleBean : descrProperties) { if - * (confLinked.getDescriptionProperties - * ().contains(tripleBean.getProperty().getNsProperty()) || - * confLinked - * .getDescriptionProperties().contains(tripleBean.getProperty - * ().getProperty())) { if (!betterDescrMatch && (descr.equals("") - * || preferredLanguage.equals(tripleBean.getLang()) || - * tripleBean.getLang().equals("en"))) { descr = - * tripleBean.getValue(); lang = tripleBean.getLang(); if - * (preferredLanguage.equals(tripleBean.getLang())) { - * betterDescrMatch = true; } } } } - * - * } - */ - - result.append(""); - - for (String img : results.getImages()) { - result.append(""); - } - for (String link : results.getLinking()) { - result.append(""); - } - result.append(""); - result.append(""); - result.append(""); - - result.append(""); - return result.toString(); - - } catch (Exception e) { - // e.printStackTrace(); - logger.error(IRI + " unable to retrieve data " + e.getMessage()); - return "" + // - messageSource.getMessage("error.linkedResourceUnavailable", null, "unable to retrieve data", locale) + // - ""; - } - } -} diff --git a/src/main/java/org/dvcama/lodview/controllers/ResourceController.java b/src/main/java/org/dvcama/lodview/controllers/ResourceController.java deleted file mode 100644 index 4bcca76..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/ResourceController.java +++ /dev/null @@ -1,408 +0,0 @@ -package org.dvcama.lodview.controllers; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang3.StringUtils; -import org.apache.jena.atlas.web.AcceptList; -import org.apache.jena.atlas.web.MediaType; -import org.apache.jena.riot.Lang; -import org.apache.jena.riot.RDFLanguages; -import org.dvcama.lodview.bean.OntologyBean; -import org.dvcama.lodview.bean.ResultBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.builder.ResourceBuilder; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.dvcama.lodview.utils.Misc; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.CookieValue; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.servlet.view.RedirectView; -import org.springframework.web.util.UrlPathHelper; - -import com.hp.hpl.jena.rdf.model.ModelFactory; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Controller -@RequestMapping(value = "/") -public class ResourceController { - - final Logger logger = LoggerFactory.getLogger(ResourceController.class); - - @Autowired - private MessageSource messageSource; - - @Autowired - ConfigurationBean conf; - - @Autowired - OntologyBean ontoBean; - - final AcceptList offeringRDF = new AcceptList("text/turtle, application/turtle, " // - + "application/x-turtle, application/rdf+xml, " // - + "application/rdf+json, application/ld+json, " // - + "text/plain, application/n-triples, text/trig, " // - + "application/n-quads, application/x-trig, application/trig, " // - + "text/n-quads, text/nquads, application/trix+xml, " // - + "text/rdf+n3, application/n3, " // - + "text/n3"); - - final AcceptList offeringResources = new AcceptList("text/html, application/xhtml+xml"); - - public ResourceController() { - - } - - public ResourceController(MessageSource messageSource, OntologyBean ontoBean) { - this.messageSource = messageSource; - this.ontoBean = ontoBean; - } - - @RequestMapping(value = { "{path:(?!staticResources).*$}", "{path:(?!staticResources).*$}/**" }) - public Object resourceController(ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "output", defaultValue = "") String output, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) throws UnsupportedEncodingException { - if (colorPair.equals("")) { - colorPair = conf.getRandomColorPair(); - Cookie c = new Cookie("colorPair", colorPair); - c.setPath("/"); - res.addCookie(c); - } - return resource(conf, model, req, res, locale, output, "", colorPair); - } - - public Object resource(ConfigurationBean conf, ModelMap model, HttpServletRequest req, HttpServletResponse res, Locale locale, String output, String forceIRI, String colorPair) throws UnsupportedEncodingException { - - model.addAttribute("conf", conf); - - String IRIsuffix = new UrlPathHelper().getLookupPathForRequest(req).replaceAll("/lodview/", "/"); - String requestUrl = req.getRequestURI(); - - logger.info("IRIsuffix " + IRIsuffix); - logger.info("requestUrl " + requestUrl); - - model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); - model.addAttribute("locale", locale.getLanguage()); - - boolean redirect = false; - boolean redirected = false; - boolean avoidRedirection = false; - - // managing redirections - if (!conf.getHttpRedirectExcludeList().equals("")) { - String[] excList = conf.getHttpRedirectExcludeList().split(","); - for (String exclude : excList) { - if (requestUrl.matches(exclude)) { - avoidRedirection = true; - break; - } - } - } - if (!avoidRedirection && !conf.getHttpRedirectSuffix().equals("")) { - // 303 dereferencing mode - if (IRIsuffix.matches(".+" + conf.getHttpRedirectSuffix() + "$")) { - // after redirect - IRIsuffix = IRIsuffix.replaceAll(conf.getHttpRedirectSuffix() + "$", ""); - - redirected = true; - } else { - // before redirect - redirect = true; - } - } else if (!avoidRedirection && !conf.getHttpRedirectPrefix().equals("")) { - // 303 dereferencing mode - if (IRIsuffix.matches("^" + conf.getHttpRedirectPrefix() + ".+")) { - // after redirect - IRIsuffix = IRIsuffix.replaceAll("^" + conf.getHttpRedirectPrefix(), ""); - if (conf.getRedirectionStrategy().equals("pubby")) { - IRIsuffix = "/resource/" + IRIsuffix; - IRIsuffix = IRIsuffix.replaceAll("//", "/"); - } - redirected = true; - } else { - // before redirect - redirect = true; - } - } - - IRIsuffix = IRIsuffix.replaceAll("^/", ""); - - String IRIprefix = conf.getIRInamespace().replaceAll("/$", ""); - String IRI = IRIprefix + "/" + IRIsuffix.replaceAll(" ", "%20"); - - if (forceIRI != null && !forceIRI.equals("")) { - IRI = forceIRI; - } - - if (conf.getForceIriEncoding().equals("encode")) { - String[] IRItokens = IRI.split("/"); - for (int i = 0; i < IRItokens.length; i++) { - IRItokens[i] = java.net.URLEncoder.encode(IRItokens[i], "UTF-8"); - } - IRI = StringUtils.join("/"); - } else if (conf.getForceIriEncoding().equals("decode")) { - String[] IRItokens = IRI.split("/"); - for (int i = 0; i < IRItokens.length; i++) { - IRItokens[i] = java.net.URLDecoder.decode(IRItokens[i], "UTF-8"); - } - IRI = StringUtils.join("/"); - } - - if (conf.getRedirectionStrategy().equals("pubby")) { - /* - * http://dbpedia.org/data/Barack_Obama.ntriples - * http://dbpedia.org/data/Barack_Obama.n3 - * http://dbpedia.org/data/Barack_Obama.json - * http://dbpedia.org/data/Barack_Obama.rdf - */ - if (requestUrl.matches(".+\\.(ntriples|n3|json|rdf)")) { - String outputType = ""; - String newUrl = requestUrl.replaceFirst("/data/", "/resource/").replaceAll("\\.(ntriples|n3|json|rdf)$", ""); - RedirectView r = new RedirectView(); - r.setExposeModelAttributes(false); - if (requestUrl.endsWith(".ntriples")) { - outputType = "text/plain"; - } else if (requestUrl.endsWith(".n3")) { - outputType = "text/turtle"; - } else if (requestUrl.endsWith(".json")) { - outputType = "application/rdf+json"; - } else if (requestUrl.endsWith(".rdf")) { - outputType = "application/rdf+xml"; - } - r.setUrl(newUrl + "?" + (req.getQueryString() != null ? req.getQueryString() + "&" : "") + "output=" + outputType); - return r; - } - } - - logger.info("####################################################################"); - logger.info("################# looking for " + IRI + " ################# "); - - String[] acceptedContent = req.getHeader("Accept").split(","); - if (redirected) { - acceptedContent = "text/html".split(","); - } - // log.trace("Accept " + req.getHeader("Accept")); - - AcceptList a = AcceptList.create(acceptedContent); - // log.trace("-- AcceptList: " + a); - // log.trace("-- OffertList: " + offeringRDF); - - MediaType matchItem = AcceptList.match(offeringRDF, a); - Lang lang = matchItem != null ? RDFLanguages.contentTypeToLang(matchItem.getContentType()) : null; - - // override content negotiation - if (!output.equals("")) { - try { - output = output.replaceAll("([a-zA-Z]) ([a-zA-Z])", "$1+$2"); - a = AcceptList.create(output.split(",")); - matchItem = AcceptList.match(offeringRDF, a); - lang = RDFLanguages.contentTypeToLang(matchItem.getContentType()); - } catch (Exception e) { - return new ErrorController(conf).error406(res, model, colorPair); - } - logger.debug("override content type " + matchItem.getContentType()); - } - - try { - if (lang == null) { - matchItem = AcceptList.match(offeringResources, a); - // probably you are asking for an HTML page - if (matchItem != null) { - if (redirect && !redirected) { - return redirect(req, IRIsuffix); - } else { - return htmlResource(model, IRI, colorPair, locale, req, res); - } - } else { - return new ErrorController(conf).error406(res, model, colorPair); - } - } else { - return resourceRaw(conf, model, IRI, conf.getEndPointUrl(), matchItem.getContentType()); - } - } catch (Exception e) { - e.printStackTrace(); - if (e.getMessage() != null && e.getMessage().startsWith("404")) { - return new ErrorController(conf).error404(res, model, e.getMessage(), colorPair, IRI, conf.getEndPointUrl()); - } else { - return new ErrorController(conf).error500(res, model, e.getMessage(), colorPair, IRI, conf.getEndPointUrl()); - } - } - - } - - private String htmlResource(ModelMap model, String IRI, String colorPair, Locale locale, HttpServletRequest req, HttpServletResponse res) throws Exception { - model.addAttribute("contextPath", new UrlPathHelper().getContextPath(req)); - ResultBean r = new ResourceBuilder(messageSource).buildHtmlResource(IRI, locale, conf, ontoBean); - model.addAttribute("colorPair", Misc.guessColor(colorPair, r, conf)); - model.addAttribute("results", Misc.guessClass(r, conf, ontoBean)); - model.addAttribute("ontoBean", ontoBean); - - addDataLinks(IRI, model, req, locale); - addLodliveLink(locale, model, IRI); - enrichResponse(model, r, req, res); - return "resource"; - } - - private void addDataLinks(String IRI, ModelMap model, HttpServletRequest req, Locale locale) throws UnsupportedEncodingException { - - Map> rawdatalinks = new LinkedHashMap>(); - String queryString = (req.getQueryString() != null ? "&" + req.getQueryString().replaceAll("&", "&") : ""); - - if (conf.getRedirectionStrategy().equals("pubby")) { - - Map list = new LinkedHashMap(); - list.put("xml", "?output=" + URLEncoder.encode("application/rdf+xml", "UTF-8") + queryString); - list.put("ntriples", "?output=" + URLEncoder.encode("text/plain", "UTF-8") + queryString); - list.put("turtle", "?output=" + URLEncoder.encode("text/turtle", "UTF-8") + queryString); - list.put("json", "?output=" + URLEncoder.encode("application/rdf+json", "UTF-8") + queryString); - list.put("ld+json", "?output=" + URLEncoder.encode("application/ld+json", "UTF-8") + queryString); - rawdatalinks.put("rdf:", list); - - } else { - Map list = new LinkedHashMap(); - list.put("xml", "?output=" + URLEncoder.encode("application/rdf+xml", "UTF-8") + queryString); - list.put("ntriples", "?output=" + URLEncoder.encode("text/plain", "UTF-8") + queryString); - list.put("turtle", "?output=" + URLEncoder.encode("text/turtle", "UTF-8") + queryString); - list.put("ld+json", "?output=" + URLEncoder.encode("application/ld+json", "UTF-8") + queryString); - rawdatalinks.put(messageSource.getMessage("footer.viewAs", null, "view as", locale), list); - } - - if (conf.getEndPointType().equals("virtuoso")) { - { - Map list = new LinkedHashMap(); - list.put("atom", conf.getEndPointUrl() + "?output=application%2Fatom%2Bxml&query=DESCRIBE+%3C" + IRI + "%3E"); - list.put("json", conf.getEndPointUrl() + "?output=application%2Fodata%2Bjson&query=DESCRIBE+%3C" + IRI + "%3E"); - rawdatalinks.put("odata:", list); - } - { - Map list = new LinkedHashMap(); - list.put("html", conf.getEndPointUrl() + "?output=text%2Fhtml&query=DESCRIBE+%3C" + IRI + "%3E"); - list.put("json", conf.getEndPointUrl() + "?output=application%2Fmicrodata%2Bjson&query=DESCRIBE+%3C" + IRI + "%3E"); - rawdatalinks.put("microdata:", list); - } - { - Map list = new LinkedHashMap(); - list.put("csv", conf.getEndPointUrl() + "?output=text%2Fcsv&query=DESCRIBE+%3C" + IRI + "%3E"); - list.put("cxml", conf.getEndPointUrl() + "?output=format=text%2Fcxml&query=DESCRIBE+%3C" + IRI + "%3E"); - rawdatalinks.put("rawdata:", list); - } - } - model.addAttribute("rawdatalinks", rawdatalinks); - - } - - private RedirectView redirect(HttpServletRequest req, String IRIsuffix) throws UnsupportedEncodingException { - - RedirectView r = new RedirectView(); - // preventing redirect of model attributes - r.setExposeModelAttributes(false); - r.setContentType("text/html"); - r.setHttp10Compatible(false); - if (!conf.getHttpRedirectPrefix().equals("")) { - // prefix mode - String redirectUrl = conf.getHttpRedirectPrefix().replaceAll("^/", ""); - if (conf.getRedirectionStrategy().equals("pubby")) { - r.setUrl(conf.getPublicUrlPrefix() + redirectUrl + IRIsuffix.replaceAll("^resource/", "") + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); - } else { - r.setUrl(conf.getPublicUrlPrefix().replaceAll(IRIsuffix + "$", "") + redirectUrl + IRIsuffix + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); - } - } else { - // suffix mode - String redirectUrl = conf.getHttpRedirectSuffix(); - // String[] redirectUrlArray = redirectUrl.split("/"); - // redirectUrl = ""; - // for (String string : redirectUrlArray) { - // redirectUrl += URLEncoder.encode(string, "UTF-8") + "/"; - // } - // redirectUrl = redirectUrl.replaceAll("/$", ""); - r.setUrl(req.getRequestURL() + redirectUrl + (req.getQueryString() != null ? "?" + req.getQueryString() : "")); - } - - return r; - - } - - private void addLodliveLink(Locale locale, ModelMap model, String IRI) { - if (locale.getLanguage().equals("it")) { - model.addAttribute("lodliveUrl", "http://lodlive.it?" + IRI.replaceAll("#", "%23")); - } else if (locale.getLanguage().equals("fr")) { - model.addAttribute("lodliveUrl", "http://fr.lodlive.it?" + IRI.replaceAll("#", "%23")); - } else if (locale.getLanguage().equals("gl")) { - model.addAttribute("lodliveUrl", "http://gl.lodlive.it?" + IRI.replaceAll("#", "%23")); - } else { - model.addAttribute("lodliveUrl", "http://en.lodlive.it?" + IRI.replaceAll("#", "%23")); - } - } - - private void enrichResponse(ModelMap model, ResultBean r, HttpServletRequest req, HttpServletResponse res) { - - String publicUrl = r.getMainIRI(); - res.addHeader("Link", "<" + publicUrl + ">; rel=\"about\""); - - @SuppressWarnings("unchecked") - Map> rawdatalinks = (LinkedHashMap>) model.get("rawdatalinks"); - for (String k : rawdatalinks.keySet()) { - for (String k1 : rawdatalinks.get(k).keySet()) { - res.addHeader("Link", "<" + rawdatalinks.get(k).get(k1) + ">; rel=\"alternate\"; type=\"application/rdf+xml\"; title=\"Structured Descriptor Document (" + k1 + ")\""); - } - } - try { - for (TripleBean t : r.getResources(r.getMainIRI()).get(r.getTypeProperty())) { - res.addHeader("Link", "<" + t.getProperty().getProperty() + ">; rel=\"type\""); - } - } catch (Exception e) { - // TODO: handle exception - } - } - - @RequestMapping(value = "/rawdata") - public ResponseEntity resourceRawController(ModelMap model, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "sparql") String sparql, @RequestParam(value = "contentType", defaultValue = "application/rdf+xml") String contentType) { - return resourceRaw(conf, model, IRI, sparql, contentType); - } - - public ResponseEntity resourceRaw(ConfigurationBean conf, ModelMap model, @RequestParam(value = "IRI") String IRI, @RequestParam(value = "sparql") String sparql, @RequestParam(value = "contentType", defaultValue = "application/rdf+xml") String contentType) { - // logger.trace("ResourceController.resourceRaw()"); - contentType = contentType.replaceAll("([a-zA-Z]) ([a-zA-Z])", "$1+$2"); - Lang lang = RDFLanguages.contentTypeToLang(contentType); - try { - HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", contentType + "; charset=" + conf.getContentEncoding()); - - if (sparql != null && sparql.equals("<>")) { - com.hp.hpl.jena.rdf.model.Model m = ModelFactory.createDefaultModel(); - try { - m.read(IRI); - } catch (Exception e) { - throw new Exception(messageSource.getMessage("error.noContentNegotiation", null, "sorry but content negotiation is not supported by the IRI", Locale.ENGLISH)); - } - return new ResponseEntity(new ResourceBuilder(messageSource).buildRDFResource(IRI, m, lang, conf), headers, HttpStatus.OK); - } else { - return new ResponseEntity(new ResourceBuilder(messageSource).buildRDFResource(IRI, sparql, lang, conf), headers, HttpStatus.OK); - } - - } catch (Exception e) { - if (e.getMessage() != null && e.getMessage().startsWith("404")) { - return new ResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND); - } else { - return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } - } - - } -} diff --git a/src/main/java/org/dvcama/lodview/controllers/SPARQLController.java b/src/main/java/org/dvcama/lodview/controllers/SPARQLController.java deleted file mode 100644 index 0a04531..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/SPARQLController.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.dvcama.lodview.controllers; - -import org.dvcama.lodview.conf.ConfigurationBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -@Controller -public class SPARQLController { - @Autowired - ConfigurationBean conf; - - @RequestMapping(value = { "/sparql", "/SPARQL" }) - public String sparql() { - - /* TODO: make this configurable allowing "proxy" features */ - - return "redirect:" + conf.getEndPointUrl(); - } -} diff --git a/src/main/java/org/dvcama/lodview/controllers/StaticController.java b/src/main/java/org/dvcama/lodview/controllers/StaticController.java deleted file mode 100644 index 1ba0149..0000000 --- a/src/main/java/org/dvcama/lodview/controllers/StaticController.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.dvcama.lodview.controllers; - -import java.util.Locale; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.dvcama.lodview.conf.ConfigurationBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.CookieValue; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.util.UrlPathHelper; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Controller -public class StaticController { - - final Logger logger = LoggerFactory.getLogger(StaticController.class); - - @Autowired - ConfigurationBean conf; - - @Autowired - private MessageSource messageSource; - - public StaticController() { - // TODO Auto-generated constructor stub - } - - public StaticController(MessageSource messageSource) { - this.messageSource = messageSource; - } - - @RequestMapping(value = "/") - public String home(HttpServletRequest req, HttpServletResponse res, Model model, Locale locale, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) { - colorPair = conf.getRandomColorPair(); - Cookie c = new Cookie("colorPair", colorPair); - c.setPath("/"); - res.addCookie(c); - model.addAttribute("colorPair", colorPair); - model.addAttribute("conf", conf); - model.addAttribute("locale", locale.getLanguage()); - model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); - logger.debug("home controller"); - return "home"; - } - - @RequestMapping(value = "/lodviewmenu") - public String lodviewmenu(Model model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "IRI") String IRI, @CookieValue(value = "colorPair", defaultValue = "") String colorPair) { - if (colorPair.equals("")) { - colorPair = conf.getRandomColorPair(); - Cookie c = new Cookie("colorPair", colorPair); - c.setPath("/"); - res.addCookie(c); - } - return lodviewmenu(req, res, model, locale, IRI, conf, colorPair); - } - - @RequestMapping(value = { "/lodviewcolor", "/**/lodviewcolor" }) - public ResponseEntity lodviewcolor(Model model, HttpServletRequest req, HttpServletResponse res, Locale locale, @RequestParam(value = "colorPair") String colorPair) { - Cookie c = new Cookie("colorPair", colorPair); - c.setPath("/"); - res.addCookie(c); - return new ResponseEntity(HttpStatus.OK); - } - - public String lodviewmenu(HttpServletRequest req, HttpServletResponse res, Model model, Locale locale, @RequestParam(value = "IRI", defaultValue = "") String IRI, ConfigurationBean conf, String colorPair) { - model.addAttribute("conf", conf); - model.addAttribute("locale", locale.getLanguage()); - model.addAttribute("IRI", IRI); - model.addAttribute("colorPair", colorPair); - model.addAttribute("path", new UrlPathHelper().getContextPath(req).replaceAll("/lodview/", "/")); - return "menu"; - } - -} diff --git a/src/main/java/org/dvcama/lodview/endpoint/SPARQLEndPoint.java b/src/main/java/org/dvcama/lodview/endpoint/SPARQLEndPoint.java deleted file mode 100644 index f64166f..0000000 --- a/src/main/java/org/dvcama/lodview/endpoint/SPARQLEndPoint.java +++ /dev/null @@ -1,334 +0,0 @@ -package org.dvcama.lodview.endpoint; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.jena.atlas.web.auth.HttpAuthenticator; -import org.apache.jena.atlas.web.auth.SimpleAuthenticator; -import org.dvcama.lodview.bean.OntologyBean; -import org.dvcama.lodview.bean.PropertyBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.dvcama.lodview.utils.Misc; - -import com.hp.hpl.jena.graph.Node; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.Property; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.Statement; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class SPARQLEndPoint { - - private static Logger logger = LoggerFactory.getLogger(SPARQLEndPoint.class); - - OntologyBean ontoBean; - String locale = "en"; - protected ConfigurationBean conf; - - public SPARQLEndPoint(ConfigurationBean conf, OntologyBean ontoBean, String locale) { - this.locale = locale; - this.ontoBean = ontoBean; - this.conf = conf; - // TODO Auto-generated constructor stub - } - - public List doQuery(String IRI, String aProperty, int start, List queries, String filter, String overrideProperty) throws Exception { - // logger.trace("executing query on " + conf.getEndPointUrl()); - List results = new ArrayList(); - HttpAuthenticator auth = null; - if (conf.getAuthPassword() != null && !conf.getAuthPassword().equals("")) { - auth = new SimpleAuthenticator(conf.getAuthUsername(), conf.getAuthPassword().toCharArray()); - } - for (String query : queries) { - // logger.trace("-- " + parseQuery(query, IRI, aProperty, - // start, filter)); - QueryExecution qe = QueryExecutionFactory.sparqlService(conf.getEndPointUrl(), parseQuery(query, IRI, aProperty, start, filter), auth); - results = moreThenOneQuery(qe, results, 0, overrideProperty); - qe.close(); - } - - if (results.size() == 0) { - if (IRI != null) { - boolean hasInverses = false; - for (String query : conf.getDefaultInversesTest()) { - // logger.trace("query!!! " + parseQuery(query, IRI, - // aProperty, start, filter)); - QueryExecution qe = QueryExecutionFactory.sparqlService(conf.getEndPointUrl(), parseQuery(query, IRI, aProperty, start, filter), auth); - if (!hasInverses) { - hasInverses = qe.execAsk(); - } - qe.close(); - } - if (!hasInverses) { - throw new Exception("404 - not found"); - } - } - } - return results; - } - - private List moreThenOneQuery(QueryExecution qe, List results, int retry, String overrideProperty) throws Exception { - - try { - ResultSet rs = qe.execSelect(); - while (rs.hasNext()) { - TripleBean rb = new TripleBean(); - QuerySolution qs = rs.next(); - String property = ""; - if (overrideProperty != null) { - property = overrideProperty; - } else if (qs.get("p") != null) { - property = qs.get("p").asNode().toString(); - } - - try { - if (qs.get("s") != null && !qs.get("s").asNode().toString().startsWith("http://")) { // probably - // a - // bn - rb.setIRI(qs.get("s").asNode().toString()); - rb.setNsIRI("_:" + rb.getIRI()); - } else if (qs.get("s") != null && qs.get("s").asNode().toString().startsWith("http://")) { - rb.setIRI(qs.get("s").asNode().toString()); - rb.setNsIRI(Misc.toNsResource(rb.getIRI(), conf)); - rb.setUrl(Misc.toBrowsableUrl(rb.getIRI(), conf)); - } - - PropertyBean p = new PropertyBean(); - p.setNsProperty(Misc.toNsResource(property, conf)); - p.setProperty(property); - if (ontoBean != null) { - p.setLabel(ontoBean.getEscapedValue("label", locale, property)); - p.setComment(ontoBean.getEscapedValue("comment", locale, property)); - } - p.setPropertyUrl(Misc.toBrowsableUrl(property, conf)); - rb.setProperty(p); - if (qs.get("o") != null) { - Node object = qs.get("o").asNode(); - if (object.isURI()) { - rb.setType("iri"); - rb.setValue(object.toString(false)); - } else if (object.isLiteral()) { - rb.setType("literal"); - rb.setDataType(object.getLiteralDatatypeURI()); - rb.setNsDataType(Misc.toNsResource(object.getLiteralDatatypeURI(), conf)); - rb.setLang(object.getLiteralLanguage()); - rb.setValue(object.getLiteralLexicalForm()); - } else if (object.isBlank()) { - rb.setType("bnode"); - rb.setValue(object.toString(false)); - } - } else { - rb.setType("literal"); - rb.setValue(""); - } - results.add(rb); - } catch (Exception e) { - logger.error("error? " + e.getMessage()); - // e.printStackTrace(); - } - } - } catch (Exception ez) { - if (retry < 3) { - retry++; - // logger.trace("query failed (" + ez.getMessage() + - // "), I'm giving another chance (" + retry + "/3)"); - return moreThenOneQuery(qe, results, retry, overrideProperty); - } - ez.printStackTrace(); - throw new Exception("connection refused"); - } - - return results; - } - - public List doQuery(String IRI, List queries, String overrideProperty) throws Exception { - return doQuery(IRI, null, -1, queries, null, overrideProperty); - } - - public List doLocalQuery(Model m, String IRI, List queries, String about) throws Exception { - return doLocalQuery(m, IRI, null, -1, queries, about); - } - - public List doLocalQuery(Model model, String IRI, List queries) throws Exception { - return doLocalQuery(model, IRI, null, -1, queries, null); - } - - public List doLocalQuery(Model model, String IRI, String localProperty, int start, List queries, String overrideProperty) throws Exception { - // logger.trace("executing query on model based on " + IRI); - List results = new ArrayList(); - - for (String query : queries) { - QueryExecution qe = QueryExecutionFactory.create(parseQuery(query, IRI, localProperty, start, null), model); - try { - ResultSet rs = qe.execSelect(); - while (rs.hasNext()) { - TripleBean rb = new TripleBean(); - QuerySolution qs = rs.next(); - String property = ""; - if (overrideProperty != null) { - property = overrideProperty; - } else if (qs.get("p") != null) { - property = qs.get("p").asNode().toString(); - } - try { - if (qs.get("s") != null && !qs.get("s").asNode().toString().startsWith("http://")) { // probably - // blanknode - rb.setIRI(qs.get("s").asNode().toString()); - rb.setNsIRI("_:" + rb.getIRI()); - } else if (qs.get("s") != null && qs.get("s").asNode().toString().startsWith("http://")) { - rb.setIRI(qs.get("s").asNode().toString()); - rb.setNsIRI(Misc.toNsResource(rb.getIRI(), conf)); - rb.setUrl(Misc.toBrowsableUrl(rb.getIRI(), conf)); - } - PropertyBean p = new PropertyBean(); - p.setNsProperty(Misc.toNsResource(property, conf)); - p.setProperty(property); - p.setPropertyUrl(Misc.toBrowsableUrl(property, conf)); - if (ontoBean != null) { - p.setLabel(ontoBean.getEscapedValue("label", locale, property)); - p.setComment(ontoBean.getEscapedValue("comment", locale, property)); - } - rb.setProperty(p); - if (qs.get("o") != null) { - Node object = qs.get("o").asNode(); - if (object.isURI()) { - rb.setType("iri"); - rb.setValue(object.toString(false)); - } else if (object.isLiteral()) { - rb.setType("literal"); - rb.setDataType(object.getLiteralDatatypeURI()); - rb.setNsDataType(Misc.toNsResource(object.getLiteralDatatypeURI(), conf)); - rb.setLang(object.getLiteralLanguage()); - rb.setValue(object.getLiteralLexicalForm()); - } else if (object.isBlank()) { - rb.setType("bnode"); - rb.setValue(object.toString(false)); - } - } else { - rb.setType("literal"); - rb.setValue(""); - } - results.add(rb); - } catch (Exception e) { - logger.error("error? " + e.getMessage()); - e.printStackTrace(); - } - } - } catch (Exception e) { - throw new Exception("500 - " + e.getMessage()); - } finally { - qe.close(); - } - } - - if (results.size() == 0) { - throw new Exception("404 - not found"); - } - return results; - } - - public Model extractData(Model result, String IRI, String sparql, List queries) throws Exception { - - // logger.trace("executing query on " + sparql); - Resource subject = result.createResource(IRI); - for (String query : queries) { - QueryExecution qe = QueryExecutionFactory.sparqlService(sparql, parseQuery(query, IRI, null, -1, null)); - try { - ResultSet rs = qe.execSelect(); - - List sl = new ArrayList(); - while (rs.hasNext()) { - QuerySolution qs = rs.next(); - RDFNode subject2 = qs.get("s"); - RDFNode property = qs.get("p"); - RDFNode object = qs.get("o"); - result.add(result.createStatement(subject2 != null ? subject2.asResource() : subject, property.as(Property.class), object)); - } - result.add(sl); - } catch (Exception e) { - e.printStackTrace(); - throw new Exception("error in query execution: " + e.getMessage()); - } finally { - qe.close(); - } - } - return result; - } - - public Model extractLocalData(Model result, String IRI, Model m, List queries) throws Exception { - - // logger.trace("executing query on IRI"); - Resource subject = result.createResource(IRI); - for (String query : queries) { - QueryExecution qe = QueryExecutionFactory.create(parseQuery(query, IRI, null, -1, null), m); - try { - ResultSet rs = qe.execSelect(); - List sl = new ArrayList(); - while (rs.hasNext()) { - QuerySolution qs = rs.next(); - RDFNode subject2 = qs.get("s"); - RDFNode property = qs.get("p"); - RDFNode object = qs.get("o"); - result.add(result.createStatement(subject2 != null ? subject2.asResource() : subject, property.as(Property.class), object)); - } - result.add(sl); - } catch (Exception e) { - e.printStackTrace(); - throw new Exception("error in query execution: " + e.getMessage()); - } finally { - qe.close(); - } - } - return result; - } - - public String parseQuery(String query, String IRI, String property, int start, String filter) { - if (IRI != null) { - /* managing issues depending on "$" in some IRIs */ - query = query.replaceAll("\\$\\{IRI\\}", IRI.replaceAll("\\$", "%24")).replaceAll("%24", "\\$"); - } - if (property != null) { - query = query.replaceAll("\\$\\{PROPERTY\\}", property); - } - if (filter != null) { - query = query.replaceAll("\\$\\{FILTERPROPERTY\\}", filter); - } - if (query.indexOf("STARTFROM") > 0) { - query = query.replaceAll("\\$\\{STARTFROM\\}", "" + start); - } else if (start > 0) { - query = query.replaceAll("LIMIT (.+)$", "OFFSET " + start + " LIMIT $1"); - } - return query; - } - - public String testEndpoint(ConfigurationBean conf) { - logger.info("testing connection on " + conf.getEndPointUrl()); - QueryExecution qe = QueryExecutionFactory.sparqlService(conf.getEndPointUrl(), "select ?s {?s ?p ?o} LIMIT 1"); - String msg = ""; - try { - ResultSet rs = qe.execSelect(); - if (rs.hasNext()) { - logger.info("is online"); - msg = "online"; - } else { - logger.info("is offline"); - msg = "offline"; - } - } catch (Exception e) { - logger.info("is offline " + e.getMessage()); - msg = "offline " + e.getMessage(); - } finally { - qe.close(); - } - return msg; - } - -} diff --git a/src/main/java/org/dvcama/lodview/utils/Misc.java b/src/main/java/org/dvcama/lodview/utils/Misc.java deleted file mode 100644 index 54f47e8..0000000 --- a/src/main/java/org/dvcama/lodview/utils/Misc.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.dvcama.lodview.utils; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import org.dvcama.lodview.bean.OntologyBean; -import org.dvcama.lodview.bean.PropertyBean; -import org.dvcama.lodview.bean.ResultBean; -import org.dvcama.lodview.bean.TripleBean; -import org.dvcama.lodview.conf.ConfigurationBean; -import org.dvcama.lodview.conf.ConfigurationBean.ColorStrategy; - -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.NodeIterator; -import com.hp.hpl.jena.rdf.model.RDFNode; - -public class Misc { - - public static String toNsResource(String iri, ConfigurationBean conf) { - if (iri != null && !iri.equals("")) { - // if (iri.startsWith(conf.getIRInamespace())) { - // return conf.getNsURIPrefix(conf.getIRInamespace()) + ":" + - // iri.replaceAll(conf.getIRInamespace() + "(.+)$", "$1"); - // } else { - // } - return conf.getNsURIPrefix(iri.replaceAll("[^/#]+$", "")) + ":" + iri.replaceAll(".+[/|#]([^/#]+)$", "$1"); - - } else { - return null; - } - } - - public static String toBrowsableUrl(String value, ConfigurationBean conf) { - - if (!conf.getPublicUrlSuffix().equals("") && value.startsWith(conf.getIRInamespace())) { - try { - return conf.getPublicUrlPrefix() + "?" + conf.getPublicUrlSuffix() + "IRI=" + java.net.URLEncoder.encode(value, "UTF-8"); - } catch (UnsupportedEncodingException e) { - return value; - } - } else { - return value.replaceAll("^" + conf.getIRInamespace() + "(.+)$", conf.getPublicUrlPrefix() + "$1").replaceAll("([^:])//", "$1/"); - } - - } - - public static String guessColor(String colorPair, ResultBean r, ConfigurationBean conf) { - switch(conf.getColorStrategy()) - { - case CLASS: { - try { - List m = r.getResources(r.getMainIRI()).get(r.getTypeProperty()); - for (TripleBean tripleBean : m) - { - colorPair = conf.getColorPairMatcher().get(tripleBean.getValue()); - if(colorPair!=null) return colorPair; - } - } catch (Exception e) { - } - return conf.getColorPairMatcher().get("http://lodview.it/conf#otherClasses"); - } - case PREFIX: { - for (String prefix : conf.getColorPairMatcher().keySet()) { - if(r.getMainIRI().startsWith(prefix)) - { - return conf.getColorPairMatcher().get(prefix); - } - } - } - default: break; - } - return colorPair; - } - - public static ResultBean guessClass(ResultBean r, ConfigurationBean conf, OntologyBean ontoBean) { - try { - if (conf.getMainOntologiesPrefixes().size() > 0) { - String mainIri = r.getMainIRI(); - Map> mainResource = r.getResources(mainIri); - TreeMap> resultOrderedMap = new TreeMap>(); - - List m = new ArrayList(mainResource.get(r.getTypeProperty())); - Model model = ontoBean.getModel(); - for (TripleBean tripleBean : m) { - int dept = 0; - if (startsWithAtLeastOne(tripleBean.getValue(), conf.getMainOntologiesPrefixes())) { - dept = countFathers(tripleBean.getValue(), 0, model); - } - List l = null; - if (resultOrderedMap.get(dept) != null) { - l = resultOrderedMap.get(dept); - } else { - l = new ArrayList(); - } - l.add(tripleBean); - resultOrderedMap.put(dept, l); - // removing types - r.removeResource(tripleBean, mainIri); - } - if (resultOrderedMap.size() > 0) { - for (Integer dept : resultOrderedMap.descendingKeySet()) { - List l = resultOrderedMap.get(dept); - for (TripleBean tripleBean : l) { - // adding ordered types - r.addResource(tripleBean, mainIri); - } - } - } - } - return r; - - } catch (Exception e) { - // e.printStackTrace(); - } - return r; - } - - private static Integer countFathers(String value, int i, Model model) { - NodeIterator iter = model.listObjectsOfProperty(model.createResource(value), model.createProperty("http://www.w3.org/2000/01/rdf-schema#subClassOf")); - while (iter.hasNext()) { - RDFNode node = iter.next(); - return countFathers(node.toString(), ++i, model); - } - return i; - } - - private static boolean startsWithAtLeastOne(String value, List startsWithList) { - for (String string : startsWithList) { - if (value.startsWith(string)) { - return true; - } - } - return false; - } - - public static String stripHTML(String value) { - - value = value.replaceAll("]*>", ""); - - return value; - } - -} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..9dbe827 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.mvc.pathmatch.matching-strategy=ant_path_matcher +spring.mvc.view.prefix=/WEB-INF/views/ +spring.mvc.view.suffix=.jsp +lode.ontoDir=ontologies diff --git a/src/main/resources/conf/conf-linked.ttl b/src/main/resources/conf/conf-linked.ttl new file mode 100644 index 0000000..f67dfd0 --- /dev/null +++ b/src/main/resources/conf/conf-linked.ttl @@ -0,0 +1,124 @@ +@prefix conf: . +@prefix meta: . +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . +@prefix owl: . +@prefix dc: . +@prefix dcterms: . +@prefix foaf: . +@prefix skos: . +@prefix geo: . +@prefix ocd: . +@prefix units: . +@prefix geonames: . +@prefix void: . +@prefix dbpedia-owl: . +@prefix yago: . +@prefix gml: . +@prefix dbpedia: . +@prefix dbpprop: . +@prefix metalex: . +@prefix frbr: . +@prefix gn: . +@prefix schema-org: . +@prefix dwc: . +@prefix ibc: . +@prefix bio: . +@prefix ods: . +@prefix shoah: . +@prefix bibo: . +@prefix org: . +@prefix bbc: . + +<> a conf:Configuration; + +## EndPoint + + conf:contentEncoding "UTF-8"; + + +## default query used to get direct properties, you can add a "FROM" clause here, +## ${IRI} will be replaced, it's always recommended to specify a limit for the query + + conf:defaultQueries "select distinct * {<${IRI}> ?p ?o} LIMIT 10000"; + + +## default query used to get resource to be included in serializations different +## from HTML, it's always recommended to specify a limit for the query +## ${IRI} will be replaced + + conf:defaultRawDataQueries """select distinct * { {<${IRI}> ?p ?o} + UNION + {<${IRI}> ?p1 ?s . ?s ?p ?o FILTER(isBlank(?s))} + } LIMIT 10000""" ; + +## skip domains that are probably offline + + conf:skipDomains "ace.dbpedia.org" , "af.dbpedia.org" , "als.dbpedia.org" , "am.dbpedia.org" , "an.dbpedia.org" , + "ang.dbpedia.org" , "ar.dbpedia.org" , "arc.dbpedia.org" , "arz.dbpedia.org" , "ast.dbpedia.org" , + "ay.dbpedia.org" , "az.dbpedia.org" , "ba.dbpedia.org" , "bar.dbpedia.org" , "bat_smg.dbpedia.org" , + "bcl.dbpedia.org" , "be.dbpedia.org" , "be_x_old.dbpedia.org" , "bg.dbpedia.org" , "bi.dbpedia.org" , + "bn.dbpedia.org" , "bo.dbpedia.org" , "br.dbpedia.org" , "bs.dbpedia.org" , "bxr.dbpedia.org" , + "ca.dbpedia.org" , "cbk_zam.dbpedia.org" , "ce.dbpedia.org" , "ceb.dbpedia.org" , "chy.dbpedia.org" , + "ckb.dbpedia.org" , "co.dbpedia.org" , "crh.dbpedia.org" , "csb.dbpedia.org" , "cu.dbpedia.org" , + "cv.dbpedia.org" , "cy.dbpedia.org" , "da.dbpedia.org" , "diq.dbpedia.org" , "dsb.dbpedia.org" , + "ee.dbpedia.org" , "eo.dbpedia.org" , "et.dbpedia.org" , "ext.dbpedia.org" , "fa.dbpedia.org" , + "fi.dbpedia.org" , "fiu_vro.dbpedia.org" , "fo.dbpedia.org" , "frp.dbpedia.org" , "frr.dbpedia.org" , + "fur.dbpedia.org" , "fy.dbpedia.org" , "ga.dbpedia.org" , "gag.dbpedia.org" , "gan.dbpedia.org" , + "gd.dbpedia.org" , "gl.dbpedia.org" , "gn.dbpedia.org" , "got.dbpedia.org" , "gv.dbpedia.org" , + "he.dbpedia.org" , "hi.dbpedia.org" , "hif.dbpedia.org" , "hr.dbpedia.org" , "hsb.dbpedia.org" , + "ht.dbpedia.org" , "hu.dbpedia.org" , "hy.dbpedia.org" , "ia.dbpedia.org" , "ie.dbpedia.org" , + "ilo.dbpedia.org" , "io.dbpedia.org" , "is.dbpedia.org" , "jbo.dbpedia.org" , "jv.dbpedia.org" , + "ka.dbpedia.org" , "kaa.dbpedia.org" , "kg.dbpedia.org" , "kk.dbpedia.org" , "kl.dbpedia.org" , + "km.dbpedia.org" , "kn.dbpedia.org" , "krc.dbpedia.org" , "ku.dbpedia.org" , "kv.dbpedia.org" , + "kw.dbpedia.org" , "la.dbpedia.org" , "lad.dbpedia.org" , "lb.dbpedia.org" , "lez.dbpedia.org" , + "li.dbpedia.org" , "lij.dbpedia.org" , "lmo.dbpedia.org" , "ln.dbpedia.org" , "lt.dbpedia.org" , + "lv.dbpedia.org" , "mdf.dbpedia.org" , "mg.dbpedia.org" , "mhr.dbpedia.org" , "mi.dbpedia.org" , + "mk.dbpedia.org" , "ml.dbpedia.org" , "mn.dbpedia.org" , "mr.dbpedia.org" , "ms.dbpedia.org" , + "mt.dbpedia.org" , "mwl.dbpedia.org" , "my.dbpedia.org" , "na.dbpedia.org" , "nah.dbpedia.org" , + "nap.dbpedia.org" , "nds.dbpedia.org" , "nds_nl.dbpedia.org" , "ne.dbpedia.org" , "new.dbpedia.org" , + "nn.dbpedia.org" , "no.dbpedia.org" , "nov.dbpedia.org" , "nrm.dbpedia.org" , "oc.dbpedia.org" , + "or.dbpedia.org" , "os.dbpedia.org" , "pa.dbpedia.org" , "pap.dbpedia.org" , "pcd.dbpedia.org" , + "pdc.dbpedia.org" , "pms.dbpedia.org" , "pnb.dbpedia.org" , "pnt.dbpedia.org" , "qu.dbpedia.org" , + "rm.dbpedia.org" , "rn.dbpedia.org" , "ro.dbpedia.org" , "roa_rup.dbpedia.org" , "roa_tara.dbpedia.org" , + "ru.dbpedia.org" , "rue.dbpedia.org" , "rw.dbpedia.org" , "sa.dbpedia.org" , "sah.dbpedia.org" , + "sc.dbpedia.org" , "scn.dbpedia.org" , "sco.dbpedia.org" , "se.dbpedia.org" , "sg.dbpedia.org" , + "sh.dbpedia.org" , "si.dbpedia.org" , "simple.dbpedia.org" , "sk.dbpedia.org" , "sl.dbpedia.org" , + "so.dbpedia.org" , "sq.dbpedia.org" , "sr.dbpedia.org" , "srn.dbpedia.org" , "stq.dbpedia.org" , + "su.dbpedia.org" , "sv.dbpedia.org" , "sw.dbpedia.org" , "szl.dbpedia.org" , "ta.dbpedia.org" , + "te.dbpedia.org" , "tg.dbpedia.org" , "th.dbpedia.org" , "tk.dbpedia.org" , "tl.dbpedia.org" , + "tpi.dbpedia.org" , "tr.dbpedia.org" , "tt.dbpedia.org" , "ty.dbpedia.org" , "udm.dbpedia.org" , + "ug.dbpedia.org" , "uk.dbpedia.org" , "ur.dbpedia.org" , "uz.dbpedia.org" , "ve.dbpedia.org" , + "vec.dbpedia.org" , "vep.dbpedia.org" , "vi.dbpedia.org" , "vls.dbpedia.org" , "vo.dbpedia.org" , + "war.dbpedia.org" , "wo.dbpedia.org" , "wuu.dbpedia.org" , "xmf.dbpedia.org" , "yi.dbpedia.org" , + "yo.dbpedia.org" , "zea.dbpedia.org" , "zh.dbpedia.org" , "zh_classical.dbpedia.org" , "zh_min_nan.dbpedia.org" , + "zh_yue.dbpedia.org" , "eml.dbpedia.org" , "ksh.dbpedia.org" , "pfl.dbpedia.org" , "zh-yue.dbpedia.org" , + "zh-min-nan.dbpedia.org" , "be-x-old.dbpedia.org" , "bat-smg.dbpedia.org" ; + + +######################################################################################## +######################## configuring the webapp ######################## +######################################################################################## + + +## document specific property used in the HTML resource page, it's possible to use +## prefixes or not + + conf:typeProperties rdf:type; + conf:titleProperties dc:title , dcterms:title, rdfs:label , , , , gn:officialName , gn:name , rdf:value , foaf:surname , , , schema-org:name, ; + conf:descriptionProperties rdfs:comment , skos:definition , dc:description , dcterms:description , dbpedia-owl:abstract ; + conf:imageProperties foaf:depiction; + conf:longitudeProperties geo:long; + conf:latitudeProperties geo:lat; + conf:linkingProperties owl:sameAs , skos:exactMatch , dbpedia-owl:wikiPageRedirects; + + +## preferred language for title and description ("auto" for delegate to the client) + + conf:preferredLanguage "auto"; ## eg. "en" or "it" + + +## just a marker to insert a point on the last row + + conf:last "." . \ No newline at end of file diff --git a/src/main/resources/conf/conf.ttl b/src/main/resources/conf/conf.ttl new file mode 100644 index 0000000..1b01b53 --- /dev/null +++ b/src/main/resources/conf/conf.ttl @@ -0,0 +1,225 @@ +@prefix conf: . +@prefix meta: . +@prefix rdf: . +@prefix rdfs: . +@prefix xsd: . +@prefix owl: . +@prefix dc: . +@prefix dcterms: . +@prefix foaf: . +@prefix skos: . +@prefix geo: . +@prefix ocd: . +@prefix units: . +@prefix geonames: . +@prefix void: . +@prefix dbpedia-owl: . +@prefix yago: . +@prefix gml: . +@prefix dbpedia: . +@prefix dbpprop: . +@prefix metalex: . +@prefix frbr: . +@prefix gn: . +@prefix schema-org: . +@prefix dwc: . +@prefix ibc: . +@prefix bio: . +@prefix ods: . +@prefix shoah: . +@prefix bibo: . +@prefix org: . +@prefix bbc: . +@prefix npg: . +@prefix prism21: . +@prefix rso: . +@prefix crm: . +@prefix bmuseum: . +@prefix bbc: . +@prefix po: . +@prefix lgdo: . +@prefix oad: . +@prefix crm-owl: . +@prefix aemetonto: . +@prefix bibleontology: . +@prefix cdoc: . +@prefix cc: . +@prefix prov: . +@prefix skos-xl: . +@prefix muninn: . +@prefix eac-cpf: . +@prefix time: . +@prefix claros: . +@prefix crm120111: . +@prefix rel: . + + +<> a conf:Configuration; + +## first of all +## IRIs namespace we use to replace the webapp base (eg. http://localhost:8080/lodview/), an +## installation on dbpedia domain should use + + conf:IRInamespace ; + +## EndPoint + + conf:endpoint ; + conf:endpointType "virtuoso"; ## just "virtuoso" is handled right now, this will add some "rawdata" + ## options in the footer, leave this blank if you don't want these links + +########## give it a try opening http://localhost:8080/lodview/Rome + + +## we don't like it so much, but you can set a prefix to activate 303 redirects +## to the HTML representation of the resources, live it blank if you want to +## use the "pure content negotiation mode", WARNING use suffix OR prefix, not both + + conf:httpRedirectSuffix ".html"; ## or eg. ".html"; + ##conf:httpRedirectPrefix "/page/"; ## or eg. ""; + + ##conf:httpRedirectExcludeList ""; ## a comma separeted list of regex to match which resources will use "pure content negotiation mode" + ## usually you have to leave this blank but if conf:redirectionStrategy is setted to "pubby" this could be + ## useful (eg. dbpedia uses /resource --> /page but leaves /ontology --> /ontology) + + conf:redirectionStrategy ""; ## set it to "pubby" to use exactly the dbpedia redirection behaviour + + + +## mode configurations + + conf:contentEncoding "UTF-8"; + + ## base64 HTTP authentication to the endpoint + conf:authUsername ""; + conf:authPassword ""; + + + +## default query used to get direct properties, you can add a "FROM" clause here, +## ${IRI} will be replaced, it's always recommended to specify a limit for the query +## the query can be seplified removing the last 2 unions to improve performance (usually not needed) + + conf:defaultQueries """select distinct ?s ?p ?o { + {<${IRI}> ?p ?o} + UNION + {<${IRI}> ?p1 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + UNION + {<${IRI}> ?p1 ?s1 . FILTER(isBlank(?s1)) . ?s1 ?p2 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + UNION + {<${IRI}> ?p1 ?s1 . FILTER(isBlank(?s1)) . ?s1 ?p2 ?s2 . FILTER(isBlank(?s2)) . ?s2 ?p3 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + } LIMIT 10000""" ; + + +## default query used to get resource to be included in serializations different +## from HTML, it's always recommended to specify a limit for the query +## ${IRI} will be replaced +## the query can be seplified removing the last 2 unions to improve performance (usually not needed) + + conf:defaultRawDataQueries """select distinct ?s ?p ?o { + {<${IRI}> ?p ?o} + UNION + {<${IRI}> ?p1 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + UNION + {<${IRI}> ?p1 ?s1 . FILTER(isBlank(?s1)) . ?s1 ?p2 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + UNION + {<${IRI}> ?p1 ?s1 . FILTER(isBlank(?s1)) . ?s1 ?p2 ?s2 . FILTER(isBlank(?s2)) . ?s2 ?p3 ?s . FILTER(isBlank(?s)) . ?s ?p ?o} + } LIMIT 10000""" ; + + +## default query used to extract inverse relations + + conf:defaultInversesQueries "select distinct ?p {?p <${PROPERTY}> <${IRI}>.} OFFSET ${STARTFROM} LIMIT 10"; + conf:defaultInversesCountQueries "select (count(distinct ?s) AS ?o) ?p {?s ?p <${IRI}>. FILTER(!isBlank(?s))} GROUP BY ?p LIMIT 100"; + conf:defaultInversesTest "ASK {?s ?p <${IRI}>}"; + +## define if inverse relations have to be automatically opened (open|close) + conf:defaultInverseBehaviour "close"; + +######################################################################################## +######################## configuring the webapp ######################## +######################################################################################## + +## define how clients access your app, typically you have to specify your public domain +## if you are using a proxy, set it at for testing, an installation on dbpedia +## domain should use + + conf:publicUrlPrefix ; ## or + + +## solve IRI issues in particular environments (proxypass, etc.) + + conf:forceIriEncoding "auto"; ## or "decode" or "encode" + +## home link (accessible from the banner) + + conf:homeUrl ; + + +## static resources publishing point, "staticResources/" is needed if you are going +## to serve static content within the web application, probably on a production +## environment you have to change "http://localhost:8080/lodview/" to something like +## "http://data.yourdomain.com/staticResources/", on a test environment you can set it +## at + + conf:staticResourceURL ; + +## choosing the lower class in hierarchy to put it on the top right of the page +## put in mainOntologies the prefixes you need to filter the resource's classes +## you need also to add the ontology file in WEB-INF/ontologies +## leave conf:mainOntologies blank if you don't want lodlive do this job + +## conf:mainOntologiesPrefixes YOUR-PREFIX:; + +## document specific property used in the HTML resource page, it's possible to use +## prefixes or not + + conf:typeProperties rdf:type; + + conf:titleProperties dc:title , dcterms:title, rdfs:label , , + , , + gn:officialName , gn:name , rdf:value , foaf:surname , , ; + + conf:descriptionProperties rdfs:comment , dc:description , dcterms:description , + dc:description , skos:definition , ; + + conf:imageProperties foaf:depiction , , crm-owl:P138i_has_representation , + ; + + conf:longitudeProperties geo:long; + conf:latitudeProperties geo:lat; + conf:linkingProperties owl:sameAs , skos:exactMatch , gn:locatedIn , ; + + conf:videoProperties ; + conf:audioProperties ; + +## preferred language for title and description ("auto" for delegate to the client) + + conf:preferredLanguage "auto"; ## eg. "en" or "it" + + +## interface colors, choose a pair or a list for random colors + + conf:colorPair "#06c-#0059b3" ; + +#### or bind classes and colors +## +## conf:colorPair conf:byClass; + + +## license information (will be added at the very end of the page) + + conf:license "" ; ## eg. "Licensed under Creative Commons Attribution 4.0 International (CC BY 4.0)" ; + +## just a marker to insert a point on the last row + + conf:last ".". + +#### uncomment only if you have configured "colors by class" +## +## conf:hasColorPair "#c3a116-#ac8c13". +## ontology:Place conf:hasColorPair "#715287-#624775". +## conf:hasColorPair "#914848-#7d3e3e". +## conf:hasColorPair "#6d8058-#5e6f4c". +## conf:hasColorPair "#5b8a97-#4f7783". +## conf:hasColorPair "#528775-#477565". diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml deleted file mode 100644 index 80e6c5c..0000000 --- a/src/main/resources/logback.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - true - - - - - - - - %-5level %logger{0} - %msg%n - - - - - - - - - - diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties deleted file mode 100644 index de515ef..0000000 --- a/src/main/resources/messages_en.properties +++ /dev/null @@ -1,37 +0,0 @@ -label.resource = resource -label.resources = resources -label.connectedResource = connected resource -label.connectedResources = connected resources -label.toTop = to top -label.go = go -label.inverseProperty = is {0} of -label.moreExample = see more examples -label.anEntityOfType = an entity of type - -title.colorPicker = pick a color -title.blankNodes = blank nodes -title.lodCloud = data from the linked data cloud -title.inverse = inverse relations -title.lookingAt = now looking at -title.directRelations = direct relations -title.pickExample = pick an example - -error.linkedResourceUnavailable = unable to retrieve data -error.noContentNegotiation = sorry but content negotiation is not supported by the IRI -error.unacceptable = you requested an unacceptable content -error.somethingWrong = Oops! something went wrong - -message.loadingConnected = loading connected resource titles -message.loadingInverses = loading inverse relations -message.grabData = retrieving data from the LOD cloud ({0} of {1}) -message.grabDataTotal = Resource connected {0} -message.grabDataTotalLoaded = Resource loaded {0} -message.grabDataTotalErrors = Resource not online {0} -message.noImage = image not available, broken URL? - -footer.noSparql = data from: dereferenceable IRI -footer.yesSparql = data from: -footer.viewLodlive = view on LodLive -footer.viewAs = view as: -footer.download = download lodview to publish your data - diff --git a/src/main/resources/messages_fr.properties b/src/main/resources/messages_fr.properties deleted file mode 100644 index 6b65057..0000000 --- a/src/main/resources/messages_fr.properties +++ /dev/null @@ -1,50 +0,0 @@ -label.resource = ressource -label.resources = ressources -label.connectedResource = ressource connectée -label.connectedResources = ressources connectées - -label.toTop = en haut -label.go = go - -label.inverseProperty = is {0} of -label.moreExample = voir plus d'exemples - -title.colorPicker = choisir une couleur -title.blankNodes = nœuds anonymes -title.lodCloud = donnée du "linked Data Cloud" -title.inverse = relations inverses - -title.lookingAt = maintenant on observe -title.directRelations = relations directes -title.pickExample = choisir un exemple - -error.linkedResourceUnavailable = impossible de retrouver les données -error.noContentNegotiation = désolé, la négociation de contenu n'est pas supportée par cette IRI -error.unacceptable = vous avez demandé un contenu inacceptable -error.somethingWrong = Oops! y'a un truc qui va pas. - -message.loadingConnected = chargement des titres de la ressource connectée -message.loadingInverses = chargemement des relations inverses -message.grabData = chargement des données depuis le cloud LOD({0} sur {1}) -message.grabDataTotal = Ressources connectées {0} -message.grabDataTotalLoaded = Ressources chargées {0} -message.grabDataTotalErrors = Ressources hors ligne {0} -message.noImage = image non disponible. (lien cassé ?) - -footer.noSparql = donnée venant de : IRI déréférençable -footer.yesSparql = donnée venant de: -footer.viewLodlive = visualiser sur LodLive -footer.viewAs = visualiser comme: -footer.download = télécharger Lodview pour publier vos données - -home.iriInput = IRI (OBLIGATOIRE) -home.sparqlInput = SPARQL ENDPOINT (OPTIONNEL) -home.prefixInput = PREFIX (OPTIONNEL) - -home.iriInfo = mettre une IRI déréférençable ou une ressource publiée sur un point d'accès SPARQL -home.sparqlInfo = URL du point d'accès SPARQL - ex http://dbpedia.org/sparql -home.prefixInfo = Préfixe de la ressource, utile pour améliorer le rendu dans le navigateur - ex http://dbpedia.org/resource - -home.share = PARTAGER -home.download = TELECHARGER -home.examples = EXEMPLES \ No newline at end of file diff --git a/src/main/resources/messages_gl.properties b/src/main/resources/messages_gl.properties deleted file mode 100644 index 8277d71..0000000 --- a/src/main/resources/messages_gl.properties +++ /dev/null @@ -1,49 +0,0 @@ -label.resource = recurso -label.resources = recursos -label.connectedResource = recurso conectado -label.connectedResources = recursos conectados -label.toTop = inicio da páxina -label.inverseProperty = é {0} de -label.go = vai -label.moreExample = ver máis exemplos -label.anEntityOfType = unha entidade de tipo - -title.colorPicker = seleccione unha cor -title.blankNodes = nodos anónimos -title.lodCloud = datos da Linked Data Cloud -title.inverse = relacións inversas -title.lookingAt = recurso actual -title.directRelations = relacións directas -title.pickExample = seleccione un exemplo - -error.linkedResourceUnavailable = non foi posíbel obter os datos -error.noContentNegotiation = sentímolo, a IRI non permite a negociación de contidos -error.unacceptable = solicitouse un contido inaceptábel -error.somethingWrong = Oh! algo non funcionou - -message.loadingConnected = cargando os títulos dos recursos conectados -message.loadingInverses = cargando as relacións inversas -message.grabData = recuperando datos da LOD cloud ({0} de {1}) -message.grabDataTotal = recursos conectados {0} -message.grabDataTotalLoaded = recursos cargados {0} -message.grabDataTotalErrors = recursos que non están en liña {0} -message.noImage = imaxe non dispoñíbel, erro na URL? - -footer.noSparql = datos de: IRI diferenciada -footer.yesSparql = datos de: -footer.viewLodlive = ver en LodLive -footer.viewAs = ver como: -footer.download = descargue lodview para publicar os seus datos - - -home.iriInput = IRI (OBRIGATORIO) -home.sparqlInput = PUNTO DE ACCESO SPARQL (OPCIONAL) -home.prefixInput = PREFIXO (OPCIONAL) - -home.iriInfo = indique unha IRI diferenciábel ou un recurso publicado nun punto de acceso SPARQL -home.sparqlInfo = enderezo URL do punto de acceso SPARQL; ex. http://dbpedia.org/sparql -home.prefixInfo = prefixo do recurso, útil para mellorar a navegación; ex. http://dbpedia.org/resource - -home.share = COMPARTIR -home.download = DESCARGAR -home.examples = EXEMPLOS diff --git a/src/main/resources/messages_it.properties b/src/main/resources/messages_it.properties deleted file mode 100644 index f525a93..0000000 --- a/src/main/resources/messages_it.properties +++ /dev/null @@ -1,49 +0,0 @@ -label.resource = risorsa -label.resources = risorse -label.connectedResource = risorsa connessa -label.connectedResources = risorse connesse -label.toTop = inizio pagina -label.inverseProperty = è {0} di -label.go = vai -label.moreExample = altri esempi di risorse -label.anEntityOfType = entità di tipo - -title.colorPicker = scegli un colore -title.blankNodes = blank nodes -title.lodCloud = risorse dalla linked data cloud -title.inverse = relazioni inverse -title.lookingAt = risorsa corrente -title.directRelations = relazioni dirette -title.pickExample = scegli un esempio - -error.linkedResourceUnavailable = risorsa non disponibile online -error.noContentNegotiation = spiacenti ma la IRI non supporta il content negotiation -error.unacceptable = il content richiesto non è accetabile -error.somethingWrong = Oops! qualcosa non ha funzionato - -message.loadingConnected = carico i titoli delle risorse collegate -message.loadingInverses = seguo le relazioni inverse -message.grabData = recupero dati dalla LOD cloud ({0} of {1}) -message.grabDataTotal = risorse connesse {0} -message.grabDataTotalLoaded = risorse caricate {0} -message.grabDataTotalErrors = risorse non online {0} -message.noImage = immagine non disponibile, URL errata? - -footer.noSparql = dati da: IRI dereferenziata -footer.yesSparql = dati da: -footer.viewLodlive = visualizza su LodLive -footer.viewAs = visualizza come: -footer.download = scarica lodview per pubblicare i tuoi dati - - -home.iriInput = IRI (OBBLIGATORIO) -home.sparqlInput = SPARQL ENDPOINT (OPZIONALE) -home.prefixInput = PREFIX (OPZIONALE) - -home.iriInfo = IRI deferenziabile o una risorsa pubblicata in uno SPARQL endpoint -home.sparqlInfo = indirizzo dello SPARQL endpoint - es. http://dbpedia.org/sparql -home.prefixInfo = prefisso delle risorse, utile per migliorare la navigazione - es. http://dbpedia.org/resource - -home.share = CONDIVIDI -home.download = DOWNLOAD -home.examples = ESEMPI diff --git a/src/main/resources/messages_nl.properties b/src/main/resources/messages_nl.properties deleted file mode 100644 index 2491370..0000000 --- a/src/main/resources/messages_nl.properties +++ /dev/null @@ -1,36 +0,0 @@ -label.resource = resource -label.resources = resources -label.connectedResource = connected resource -label.connectedResources = connected resources -label.toTop = naar boven -label.go = start -label.inverseProperty = is {0} van -label.moreExample = zie meer voorbeelden -label.anEntityOfType = type entiteit - -title.colorPicker = kies een kleur -title.blankNodes = blank nodes -title.lodCloud = data uit de linked data cloud -title.inverse = inverse relaties -title.lookingAt = nu in beeld -title.directRelations = directe relaties -title.pickExample = kies een voorbeeld - -error.linkedResourceUnavailable = data kan niet opgehaald worden -error.noContentNegotiation = sorry, content negotiation wordt niet ondersteund door deze IRI -error.unacceptable = content is niet geaccepteerd -error.somethingWrong = Oeps, iets ging er mis! - -message.loadingConnected = verbonden resources worden opgehaald -message.loadingInverses = inverse relaties ophalen -message.grabData = ontvangen van data uit de LOD cloud ({0} van {1}) -message.grabDataTotal = Resource verbonden` {0} -message.grabDataTotalLoaded = Resource opgehaald {0} -message.grabDataTotalErrors = Resource niet online {0} -message.noImage = afbeelding niet beschikbaar, foute URL? - -footer.noSparql = data van: herleidbare IRI -footer.yesSparql = data from: -footer.viewLodlive = bekijk in LodLive -footer.viewAs = bekijk als: -footer.download = download lodview om je data te publiceren \ No newline at end of file diff --git a/src/main/resources/messages_sk.properties b/src/main/resources/messages_sk.properties deleted file mode 100644 index ceca3f1..0000000 --- a/src/main/resources/messages_sk.properties +++ /dev/null @@ -1,49 +0,0 @@ -label.resource = zdroj -label.resources = zdroje -label.connectedResource = prepojený zdroj -label.connectedResources = prepojené zdroje -label.toTop = nahor -label.inverseProperty = je {0} z -label.go = potvrdiť -label.moreExample = viď iné príklady -label.anEntityOfType = typ entity - -title.colorPicker = vyber farbu -title.blankNodes = prázdne uzly -title.lodCloud = zdroje linked dáta cloud -title.inverse = inverzná relácia -title.lookingAt = aktuálny zdroj -title.directRelations = priama relácia -title.pickExample = vyber príklad - -error.linkedResourceUnavailable = nedostupný zdroj -error.noContentNegotiation = ľutujeme, iri nepodporuje content negotiation -error.unacceptable = neprijateľný content -error.somethingWrong = Ups, niečo sa pokazilo! - -message.loadingConnected = sťahujem názvy prepojených zdrojov -message.loadingInverses = sťahujem inverzné relácie -message.grabData = vyberám dáta z LOD cloud ({0} z {1}) -message.grabDataTotal = pripojené zdroje {0} -message.grabDataTotalLoaded = stiahnuté zdroje {0} -message.grabDataTotalErrors = nedostupné zdroje {0} -message.noImage = obrázok nedostupný, chyba v URL? - -footer.noSparql = dáta od: IRI s nepriamym odkazom -footer.yesSparql = dáta od: -footer.viewLodlive = zobraz na LodLive -footer.viewAs = zobraz ako: -footer.download = stiahni lodview pre publikáciu tvojich dát - - -home.iriInput = IRI (POVINNÝ) -home.sparqlInput = SPARQL ENDPOINT (VOLITEĽNÝ) -home.prefixInput = PREFIX (VOLITEĽNÝ) - -home.iriInfo = s nepriamym odkazom alebo zdroj publikovaný v SPARQL endpoint -home.sparqlInfo = adresa SPARQL endpoint – napr. http://dbpedia.org/sparql -home.prefixInfo = predvoľba zdrojov, užitočné pre zlepšenie navigovania – napr. http://dbpedia.org/resource - -home.share = ZDIEĽAJ -home.download = DOWNLOAD -home.examples = PRÍKLADY \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/ontologies/dbpedia_2014.owl b/src/main/resources/ontologies/dbpedia_2014.owl similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/dbpedia_2014.owl rename to src/main/resources/ontologies/dbpedia_2014.owl diff --git a/src/main/webapp/WEB-INF/ontologies/dcelements.rdf b/src/main/resources/ontologies/dcelements.rdf similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/dcelements.rdf rename to src/main/resources/ontologies/dcelements.rdf diff --git a/src/main/webapp/WEB-INF/ontologies/dcterms.rdf b/src/main/resources/ontologies/dcterms.rdf similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/dcterms.rdf rename to src/main/resources/ontologies/dcterms.rdf diff --git a/src/main/webapp/WEB-INF/ontologies/dctype.rdf b/src/main/resources/ontologies/dctype.rdf similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/dctype.rdf rename to src/main/resources/ontologies/dctype.rdf diff --git a/src/main/webapp/WEB-INF/ontologies/foaf.rdf b/src/main/resources/ontologies/foaf.rdf similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/foaf.rdf rename to src/main/resources/ontologies/foaf.rdf diff --git a/src/main/webapp/WEB-INF/ontologies/owl.ttl b/src/main/resources/ontologies/owl.ttl similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/owl.ttl rename to src/main/resources/ontologies/owl.ttl diff --git a/src/main/webapp/WEB-INF/ontologies/rdf.ttl b/src/main/resources/ontologies/rdf.ttl similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/rdf.ttl rename to src/main/resources/ontologies/rdf.ttl diff --git a/src/main/webapp/WEB-INF/ontologies/rdfs.ttl b/src/main/resources/ontologies/rdfs.ttl similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/rdfs.ttl rename to src/main/resources/ontologies/rdfs.ttl diff --git a/src/main/webapp/WEB-INF/ontologies/rel.rdf b/src/main/resources/ontologies/rel.rdf similarity index 100% rename from src/main/webapp/WEB-INF/ontologies/rel.rdf rename to src/main/resources/ontologies/rel.rdf diff --git a/src/main/resources/spring/application-config.xml b/src/main/resources/spring/application-config.xml deleted file mode 100644 index 94f5c72..0000000 --- a/src/main/resources/spring/application-config.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - diff --git a/src/main/resources/static/staticResources/css/commons.css b/src/main/resources/static/staticResources/css/commons.css new file mode 100644 index 0000000..657c65e --- /dev/null +++ b/src/main/resources/static/staticResources/css/commons.css @@ -0,0 +1,1031 @@ +/* ********************************************** */ +/* DO NOT CHANGE THIS FILE USE custom.css INSTEAD */ +/* ********************************************** */ +.sp { + background-image: url(../img/lodview-sprite.png); + background-size: 1000px 600px; +} + +div#logoBanner div#logo { + background-size: 134px 40px; + background-image: url(../img/logo-header-lodview.png); + height: 80px; + background-position: left center; + background-repeat: no-repeat; + cursor: pointer; + width: 150px; +} + +a { + text-decoration: none; +} + +body { + font-family: 'Roboto', sans-serif; + font-weight: 300; + line-height: 20px; + font-size: 14px; + background-color: #212121; +} + +strong { + font-weight: 500; +} + +.value div.fixed, .valuecnt div.fixed, #abstract .c2 { + max-width: 760px; + overflow-x: hidden; +} + +label { + display: inline-block; +} + +label a { + font-weight: 300; + font-size: 14px; +} + +label a span { + font-weight: 500; +} + +div#logoBanner { + height: 80px; + background-color: #fff; + padding: 0 24px; +} + +hgroup { + display: block; + min-height: 210px; + color: #fff; + padding: 0 24px; +} + +hgroup h1 { + font-size: 32px; + padding-top: 120px; + line-height: 32px; + font-weight: 300; + margin-right: 100px; +} + +hgroup h1 span { + display: inline-block; + padding-right: 250px; +} + +#seeOnLodlive a { + display: inline-block; + width: 19px; + height: 27px; +} + +#seeOnLodlive { + background-position: -130px 0; + width: 19px; + height: 27px; + position: absolute; + top: 116px; + right: 24px; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; + filter: alpha(opacity=30); + opacity: 0.3; +} + +#seeOnLodlive:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=100); + opacity: 1; +} + +hgroup h2 > a.iri { + display: inline-block; + margin-bottom: 8px; + color: #fff; + margin-right: 8px; +} + +hgroup h2 > a.iri:hover { + text-decoration: underline; +} + +hgroup h2 > span.istance { + float: none; + display: inline-block; + margin-left: -8px; +} + + +hgroup h2 { + font-size: 16px; + padding: 8px 0 24px 0; + font-weight: 300; +} + +hgroup h2 > span a { + color: #fff; + font-weight: 300; + display: inline-block; + margin-left: 8px; + margin-top: 2px; + /*text-transform: uppercase;*/ + letter-spacing: .7; + font-size: 13px; +} + +hgroup h2 > span a span { + color: #fff; + font-weight: 500; +} + +hgroup h2 > span.istance a span.istanceOf { + font-size: 11px; + text-transform: uppercase; + font-weight: 300; +} + +header div#abstract { + padding: 24px; + color: #fff; +} + +header div#abstract .value a { + text-decoration: underline; + color: #fff; +} + +header div#abstract .value a:hover { + text-decoration: none +} + +header div#abstract label { + padding: 0 24px 0 0; +} + +header div#abstract label a { + color: #fff; +} + +header div#abstract label a span { + color: #fff; +} + +aside { + display: block; + background-color: #eee; + color: #fff; + padding: 24px 24px 16px 24px; +} + +#widgets > div#images > a:hover, #widgets > div#linking > a:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; + filter: alpha(opacity=90); + opacity: 0.9; +} + +#widgets > div#images > a { + min-width: 136px; + height: 136px; + text-align: left; + display: inline-block; + background-image: url(../img/segnaposto-immagine.png); + background-size: 48px 48px; + background-position: center center; + background-repeat: no-repeat; + margin-right: 8px; + margin-bottom: 8px; +} + +aside { + font-size: 0px +} + +aside div.noImg { + width: 125px; + height: 125px; + display: inline-block; + background-position: 0 -105px; + background-size: 300px 250px; +} + +aside div#linking, aside div#images, aside div#audio, aside div#video { + display: inline-block; +} + +aside div#resourceMapCnt { + display: inline-block; + margin-right: 8px; +} + +aside div#images a img, aside div#linking a span, aside div#resourceMapCnt map, aside div#audio .audio { + height: 136px; + display: inline-block; + width: auto; +} + +aside div#video { + height: 144px; +} + +aside div#video * { + height: 136px; + display: inline-block; + margin-right: 8px; +} + +aside div#audio .audio { + height: 136px; + display: inline-block; + width: 136px; + margin-right: 8px; + margin-bottom: 8px; + background-position: -520px -65px; +} + +aside div#linking { + margin-bottom: 8px; +} + +aside div#linking a span { + width: 136px; + background-position: -280px -65px; +} + +aside div#resourceMapCnt map { + width: 272px; + background-position: 0 -65px; +} + +.leaflet-popup-content { + color: #000 +} + +.c1, .c3 { + position: absolute +} + +h3 { + text-transform: uppercase; + letter-spacing: .7; + font-weight: 300; + color: #212121; + font-size: 11px; +} + +div#directs { + padding: 24px; + background: #fff; + color: #212121; + line-height: 20px; + font-size: 14px; + overflow-x: hidden; +} + +div#bnodes { + padding: 24px; + background: #eee; + color: #212121; + line-height: 20px; + font-size: 14px; +} + +div#inverses { + padding: 24px; + background: #d4d4d4; + color: #212121; + line-height: 20px; + font-size: 14px; +} + +.lloading { + background-image: url(../img/loading-new@2x.gif); + background-size: 22px 7px; + width: 22px; + height: 7px; + display: inline-block; + margin-right: 8px; +} + +.lloadingb { + background-image: url(../img/loading-new-nero@2x.gif); + background-size: 22px 7px; + width: 22px; + height: 7px; + display: inline-block; + margin-left: 16px; +} + +div#inverses .nextArrow { + display: inline-block; + width: 12px; + height: 14px; + margin-left: 8px; + background-position: -60px 3px; +} + +div#inverses .prevArrow { + display: inline-block; + width: 12px; + height: 14px; + margin-left: 16px; + background-position: -45px 3px; +} + +div#lodCloud { + padding: 24px 24px 16px 24px; + background: #fafafa; + color: #212121; + line-height: 16px; + font-size: 12px; + min-height: 64px; +} + +div#lodCloud map { + background-position: -260px -210px; + display: inline-block; + width: 250px; + height: 250px; +} + +div#lodCloud .connected div#counterBlock.content { + color: #fff; +} + +div.toOneLine { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.value div, .valuecnt div { + min-height: 20px +} + +.value div span.derivedTitle, .valuecnt div span.derivedTitle { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + background-repeat: no-repeat; +} + +.value div span.derivedTitle tt, .valuecnt div span.derivedTitle tt { + margin: 5px 0 0 2px; + background-position: -45px -20px; + width: 11px; + display: inline-block; + height: 10px; +} + +div#directs .value a span.derivedTitle, div#bnodes .value a span.derivedTitle, div#inverses .value a span.derivedTitle { + font-weight: 300; +} + +.value div a:hover span.derivedTitle { + text-decoration: none; +} + +div#directs .value > div:not(.value), div#bnodes .valuecnt > div:not(.value), div#inverses .value > div:not(.value) { + padding-bottom: 12px; + margin-top: 12px; + background-image: url(../img/separatoreCorto.png); + background-repeat: no-repeat; + background-size: 16px 1px; + background-position: bottom left; +} + +div#directs .c2.multiInLineBlock, div#directs .c4.multiInLineBlock { + padding-bottom: 8.5px; + padding-top: 8.5px; +} + +.multiInLine { + display: inline-block; + margin-right: 20px; + line-height: 27px; +} + +div#directs .value > div:not(.value):first-child, div#bnodes .valuecnt > div:not(.value):first-child, div#inverses .value > div:not(.value):first-child, div#inverses .value > div:not(.value):nth-of-type(n+2):not(.toOneLine):not(.toMultiLine), div#bnodes .valuecnt > div:not(.value):nth-of-type(n+2):not(.toOneLine):not(.toMultiLine) { + margin-top: 0; +} + +div#directs .value > div:not(.value):last-child, div#bnodes .valuecnt > div:not(.value):last-child, div#inverses .value > div:not(.value):last-child { + padding: 0; + background: none; +} + +div#directs label, div#bnodes label, div#inverses label { + padding: 0 24px 0 0; +} + +div#directs label a, div#bnodes label a, div#inverses label a { + color: #212121; +} + +div#directs label a span, div#bnodes label a span, div#inverses label a span { + color: #212121; +} + +div#directs .dType, div#bnodes .dType { + font-size: 14px; + font-weight: 300; + color: #9e9e9e; + position: absolute; + right: 24px; + text-align: right; + padding-left: 16px; + background-color: #fff; +} + +div#bnodes .dType { + background-color: #eee; +} + +div#directs span.clang, div#abstract span.clang, div#bnodes span.clang, div#bnodes span.clang { + display: inline-block; + text-transform: uppercase; + letter-spacing: .7; + margin-right: 5px; + cursor: pointer; + margin-bottom: 12px; +} + +div#directs span.clang.sel, div#abstract span.clang.sel, div#bnodes span.clang.sel { + text-decoration: underline; +} + +div#directs .value a, div#directs .valuecnt a, div#bnodes .value a, div#bnodes .valuecnt a, div#inverses .value a, div#inverses .valuecnt a { + font-weight: 300; + font-size: 14px; + color: #212121; +} + +div#directs .value a span, div#bnodes .value a span, div#inverses .value a span { + font-weight: 500; + color: #212121; +} + +div#directs .value a:hover, div#bnodes .value a:hover, div#inverses .value a:hover, div#directs .valuecnt a:hover, div#bnodes .valuecnt a:hover, div#inverses .valuecnt a:hover { + text-decoration: underline; +} + +div#directs .c2, div#directs .c4 { + border-bottom: 1px solid #dbdbdb; + padding-bottom: 12px; + padding-top: 12px; +} + +div#bnodes .c2, div#bnodes .c4 { + border-bottom: 1px solid #d2d2d2; + padding-bottom: 12px; + padding-top: 12px; +} + +div#inverses .c2, div#inverses .c4 { + padding-bottom: 12px; + padding-top: 12px; + border-bottom: 1px solid #b6b6b6; +} + +div#inverses .c2 .toOneLine { + min-height: 40px; +} + +div#inverses .c2.opened { + min-height: 648px; +} + +div#bnodes .c2:last-child, div#directs .c2:last-child, div#inverses .c2:last-child, div#bnodes .c4:last-child, div#directs .c4:last-child, div#inverses .c4:last-child { + border-bottom: 0; + padding-bottom: 0; + padding-top: 12px; +} + +div#directs label:nth-child(1), div#bnodes label:nth-child(1), div#inverses label:nth-child(1) { + padding-top: 0; +} + +div#directs label, div#bnodes label, div#inverses label { + padding-top: 12px; +} + +div#directs .c2:nth-child(2), div#bnodes .c2:nth-child(2), div#inverses .c2:nth-child(2), div#directs .c4:nth-child(2), div#bnodes .c4:nth-child(2), div#inverses .c4:nth-child(2) { + padding-top: 0; +} + +div#lodCloud h3 { + margin-bottom: 24px; +} + +div#lodCloud .lloading { + position: absolute; + right: 22px; + top: 28px; +} + +div#lodCloud .connected { + width: 250px; + display: inline-block; + margin-right: 16px; + vertical-align: top; + margin-bottom: 16px; +} + +div#lodCloud .connected .content { + padding: 24px; + background: #e9e9e9; +} + +div#lodCloud .connected .content :last-child { + margin-bottom: 0; +} + +div#lodCloud .connected h5 { + font-weight: 500; +} + +div#lodCloud .connected .more { + margin-top: 1px; + font-weight: 300; + letter-spacing: .7; + font-size: 11px; + text-transform: uppercase; + padding: 24px; + background: #e9e9e9; +} + +div#lodCloud .connected a.link { + color: #212121; + display: block; + margin-top: 8px; + margin-bottom: 24px; +} + +div#lodCloud .connected a:hover { + text-decoration: underline; +} + +div#lodCloud .connected span.imgCnt { + background-position: 0 -210px; + width: 250px; + display: block; +} + +div#lodCloud .connected img.main { + width: 250px; + height: auto; + background: #ffffff; + +} + +.px1 { + width: 1px; + font-size: 1px; + line-height: 1px; +} + +aside.empty, #bnodes.empty, #directs.empty, #inverses.empty, #abstract.empty { + padding: 0; + min-height: 10px; +} + +#lodCloud.empty { + padding: 0; + min-height: 5px; +} + +#inverses.empty { + padding: 0; + min-height: 20px; +} + +footer { + min-height: 176px; + color: #fff; + padding: 24px; +} + +#download { + float: left; + margin-bottom: 30px; +} + +#download a#linkGit { + margin-top: 160px; + display: block; + font-size: 11px; + text-transform: uppercase; + letter-spacing: .7; + color: #b4b4b4; + text-decoration: none; +} + +#download a:hover { + text-decoration: underline +} + +#endpoint { + position: relative; + top: -7px; + font-size: 12px; + line-height: 24px; +} + +#endpoint { + float: right; + color: #fff; +} + +#endpoint ul li { + min-height: 24px; +} + +#endpoint ul { + list-style: none; +} + +#endpoint a { + color: #fff; + cursor: pointer; +} + +#endpoint a:hover { + text-decoration: underline +} + +div#directs .value > div.lang, div#bnodes .value > div.lang, div#inverses .value > div.lang { + background: none; + padding-bottom: 0; + margin-top: 0 +} + +div#loadPanel { + position: fixed; + width: 100%; + bottom: 0; + left: 0; + line-height: 30px; + height: 30px; + padding-left: 24px; + overflow: hidden; + z-index: 1004; +} + +div#loadPanel.cfix { + padding-left: 100%; + margin-left: -300px +} + +div#loadPanel span.ok { + width: 17px; + height: 14px; + display: inline-block; + margin-left: 6px; +} + +div#loadPanel span.ok img { + display: none +} + +div#loadPanel > p { + font-family: 'Roboto', sans-serif; + font-weight: 300; + line-height: 30px; + font-size: 12px; + color: #fff; +} + +#images .errorImg { + width: 136px; + height: 136px; + margin-right: 8px; +} + +.connected .errorImg { + width: 250px; + height: 250px; +} + +#errorPage hgroup h1 { + font-size: 150px; + font-weight: 100; + padding-left: 66px; + padding-top: 80px; +} + +#errorPage.error404 div#owl { + background-image: url(../img/owl404.png); + background-size: 224px 283px; + width: 224px; + height: 283px; + position: absolute; + left: 660px; + top: 105px +} + +#errorPage.error500 div#owl { + background-image: url(../img/owl500.png); + background-size: 224px 283px; + position: absolute; + width: 224px; + height: 283px; + left: 660px; + top: 105px +} + +#errorPage div#abstract { + height: 65px; + padding: 0; +} + +#errorPage div#bnodes { + font-size: 20px; + min-height: 186px; + padding: 0 24px 24px 90px; +} + +#errorPage div#bnodes p { + font-size: 30px; + line-height: 40px; + padding-top: 60px; +} + +footer { + +} + +footer #linkBack { + display: block; + background-size: 134px 25px; + background-image: url(../img/logo-footer-lodview.png); + background-position: 0 0; + height: 25px; + width: 134px; + background-repeat: no-repeat; +} + +footer #linkBack:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=6); + opacity: 0.6; +} + +#navigator { + position: fixed; + right: 0; + top: 50%; + margin-top: -32px; + z-index: 5; + width: 40px; + height: 78px; +} + +#navigator div { + width: 40px; + height: 20px; + cursor: pointer; + margin-bottom: 1px; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=10); + opacity: 0.1; +} + +#navigator div span { + display: none; +} + +#navigator div.hover:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=10); + opacity: 1; + position: static; +} + +#navigator div.hover:hover span { + display: inline-block; + position: fixed; + right: 41px; + background-color: #222; + padding: 0 8px; + height: 20px; + color: #fff; + line-height: 20px; + font-size: 12px; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=10); + opacity: 1; +} + +#navigator div a { + display: block; + width: 40px; + height: 20px; +} + +#navigator div.down { + background-position: 0 -40px; +} + +#navigator div.up { + background-position: 0 0; +} + +#navigator div.top { + background-position: 0 -20px; +} + +@media screen and (max-width: 768px) { + hgroup h1 span { + padding-right: 150px; + } +} + +.iph { + width: 22px; + height: 20px; + position: absolute; + left: -20px; +} + +.i { + background-position: -105px -35px; + width: 22px; + height: 20px; + position: absolute; + left: -20px; + z-index: 9; + display: none; + cursor: help; +} + +.i span { + display: inline-block; + background-position: -105px -35px; + width: 11px; + height: 11px; + position: relative; + left: 4px; + top: 5px; + z-index: 9; +} + +.tooltip { + display: none; + background-color: #212121; + font-family: 'Roboto', sans-serif; + font-weight: 300; + line-height: 15px; + font-size: 12px; + color: #fff; + padding: 10px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + position: absolute; + left: 8px; + margin-top: 22px; + width: 250px; + z-index: 9; +} + +#license { + padding: 12px 0; + line-height: 20px; + font-family: 'Roboto', sans-serif; + font-weight: 300; + font-size: 12px; + float: left; + width: 100%; + background: #fff; +} + +#license div { + padding: 0 24px; +} + +#license div a { + font-weight: 500; + color: #222222 +} + +#license div a:hover { + text-decoration: underline; +} + +/* ********************************** */ +/* CUSTOM FOOTER, HIDDEN BY DEFAULT */ +/* ********************************** */ +#customFooter { + display: none; +} + +/* useful to add information about the project partners (logo) */ +#customFooter #credits { + height: 86px; + background: #e9e9e9; +} + +#customFooter #credits div { + padding: 24px 0 0 24px; +} + +/* useful to add a custom navigation menu */ +#customFooter menu { + height: 43px; + background: #d4d4d4; +} + +#customFooter menu li { + margin: 0 -8px 0 0; + padding: 0 0 0 24px; + font-family: 'Roboto', sans-serif; + font-weight: 300; + font-size: 12px; + display: inline-block; + line-height: 43px; +} + +#customFooter menu li a { + color: #000; +} + +#customFooter menu li a:hover { + text-decoration: underline; +} + +/** image zoomer **/ +#hover { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + background: #fff; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; + filter: alpha(opacity=90); + display: none; + z-index: 1006; +} + +div.hover { + position: fixed; + z-index: 1007; +} + +div.closemapzoom { + width: 14px; + height: 14px; + display: inline-block; + background-position: -120px -35px; + position: fixed; + right: 19px; + top: 19px; + cursor: pointer; + +} + +img.hover { + position: fixed; + z-index: 1007; + top: 100%; + left: 100%; + display: none; +} + +.imgTools { + position: absolute; + overflow: hidden; + z-index: 999; + display: none; +} + +.imgTools .zoom { + width: 29px; + height: 29px; + background-position: -430px -65px; + display: block; + cursor: pointer; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + opacity: 0.6; +} + +.imgTools .open:hover, .imgTools .zoom:hover { + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; + filter: alpha(opacity=100); + opacity: 1; +} + +.imgTools .open { + margin-bottom: 5px; + cursor: pointer; + width: 14px; + height: 14px; + background-position: -430px -94px; + display: block; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; + filter: alpha(opacity=60); + opacity: 0.6; +} diff --git a/src/main/resources/static/staticResources/css/commons_2x.css b/src/main/resources/static/staticResources/css/commons_2x.css new file mode 100644 index 0000000..7b640f5 --- /dev/null +++ b/src/main/resources/static/staticResources/css/commons_2x.css @@ -0,0 +1,36 @@ +/* **************************************** */ +/* SPECIAL DIRECTIVES FOR PIXEL RATIO > 1 */ +/* **************************************** */ +@media ( -webkit-min-device-pixel-ratio: 2) , ( min-resolution: 192dpi) { + .sp { + background-image: url(../img/lodview-sprite@2x.png); + } + + div#logoBanner div#logo { + background-image: url(../img/logo-header-lodview@2x.png); + } + + footer #linkBack { + background-image: url(../img/logo-footer-lodview@2x.png); + } + + div#directs .value > div:not (.value ), div#bnodes .valuecnt > div:not (.value ), div#inverses .value > div:not (.value ) { + background-image: url("img/separatoreCorto@2x.png"); + } + + div#directs .value > div.lang, div#bnodes .value > div.lang, div#inverses .value > div.lang { + background: none + } + + #errorPage.error404 div#owl { + background-image: url(../img/owl404@2x.png); + } + + #errorPage.error500 div#owl { + background-image: url(../img/owl500@2x.png); + } + + #widgets > div#images > a { + background-image: url(../img/segnaposto-immagine@2x.png); + } +} diff --git a/src/main/resources/static/staticResources/css/custom.css b/src/main/resources/static/staticResources/css/custom.css new file mode 100644 index 0000000..1b7bede --- /dev/null +++ b/src/main/resources/static/staticResources/css/custom.css @@ -0,0 +1,34 @@ +/* ***************** */ +/* CUSTOM CSS HERE */ +/* ***************** */ +div#logoBanner div#logo { + background-size: 134px 40px; + background-image: url(../img/logo-header-lodview.png) !important; + height: 80px; + background-position: left center; + background-repeat: no-repeat; + cursor: pointer; + width: 150px; +} + +@media ( -webkit-min-device-pixel-ratio: 2) , ( min-resolution: 192dpi) { + div#logoBanner div#logo { + background-image: url(../img/logo-header-lodview@2x.png) !important; + } +} + +body { + background-color: #00264d !important; +} + +div#inverses { + background: #cce6ff !important; +} + + +/* ********************************** */ +/* CUSTOM FOOTER, HIDDEN BY DEFAULT */ +/* ********************************** */ +#customFooter { + display: none; +} diff --git a/src/main/resources/static/staticResources/css/reset.css b/src/main/resources/static/staticResources/css/reset.css new file mode 100644 index 0000000..21813d0 --- /dev/null +++ b/src/main/resources/static/staticResources/css/reset.css @@ -0,0 +1,78 @@ +/* html5doctor.com Reset v1.6.1 (http://html5doctor.com/html-5-reset-stylesheet/) - http://cssreset.com */ +html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent +} + +body { + line-height: 1 +} + +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block +} + +nav ul { + list-style: none +} + +blockquote, q { + quotes: none +} + +blockquote:before, blockquote:after, q:before, q:after { + content: none +} + +a { + margin: 0; + padding: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent +} + +ins { + background-color: #ff9; + color: #000; + text-decoration: none +} + +mark { + background-color: #ff9; + color: #000; + font-style: italic; + font-weight: bold +} + +del { + text-decoration: line-through +} + +abbr[title], dfn[title] { + border-bottom: 1px dotted; + cursor: help +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0 +} + +input, select { + vertical-align: middle +} diff --git a/src/main/webapp/resources/img/favicon.png b/src/main/resources/static/staticResources/img/favicon.png similarity index 100% rename from src/main/webapp/resources/img/favicon.png rename to src/main/resources/static/staticResources/img/favicon.png diff --git a/src/main/webapp/resources/img/loading-new-nero@2x.gif b/src/main/resources/static/staticResources/img/loading-new-nero@2x.gif similarity index 100% rename from src/main/webapp/resources/img/loading-new-nero@2x.gif rename to src/main/resources/static/staticResources/img/loading-new-nero@2x.gif diff --git a/src/main/webapp/resources/img/loading-new@2x.gif b/src/main/resources/static/staticResources/img/loading-new@2x.gif similarity index 100% rename from src/main/webapp/resources/img/loading-new@2x.gif rename to src/main/resources/static/staticResources/img/loading-new@2x.gif diff --git a/src/main/webapp/resources/img/loading-newB-nero@2x.gif b/src/main/resources/static/staticResources/img/loading-newB-nero@2x.gif similarity index 100% rename from src/main/webapp/resources/img/loading-newB-nero@2x.gif rename to src/main/resources/static/staticResources/img/loading-newB-nero@2x.gif diff --git a/src/main/webapp/resources/img/lodview-sprite.png b/src/main/resources/static/staticResources/img/lodview-sprite.png similarity index 100% rename from src/main/webapp/resources/img/lodview-sprite.png rename to src/main/resources/static/staticResources/img/lodview-sprite.png diff --git a/src/main/webapp/resources/img/lodview-sprite@2x.png b/src/main/resources/static/staticResources/img/lodview-sprite@2x.png similarity index 100% rename from src/main/webapp/resources/img/lodview-sprite@2x.png rename to src/main/resources/static/staticResources/img/lodview-sprite@2x.png diff --git a/src/main/webapp/resources/img/lodview_sharer.png b/src/main/resources/static/staticResources/img/lodview_sharer.png similarity index 100% rename from src/main/webapp/resources/img/lodview_sharer.png rename to src/main/resources/static/staticResources/img/lodview_sharer.png diff --git a/src/main/webapp/resources/img/logo-footer-lodview.png b/src/main/resources/static/staticResources/img/logo-footer-lodview.png similarity index 100% rename from src/main/webapp/resources/img/logo-footer-lodview.png rename to src/main/resources/static/staticResources/img/logo-footer-lodview.png diff --git a/src/main/webapp/resources/img/logo-footer-lodview@2x.png b/src/main/resources/static/staticResources/img/logo-footer-lodview@2x.png similarity index 100% rename from src/main/webapp/resources/img/logo-footer-lodview@2x.png rename to src/main/resources/static/staticResources/img/logo-footer-lodview@2x.png diff --git a/src/main/webapp/resources/img/logo-header-lodview.png b/src/main/resources/static/staticResources/img/logo-header-lodview.png similarity index 100% rename from src/main/webapp/resources/img/logo-header-lodview.png rename to src/main/resources/static/staticResources/img/logo-header-lodview.png diff --git a/src/main/webapp/resources/img/logo-header-lodview@2x.png b/src/main/resources/static/staticResources/img/logo-header-lodview@2x.png similarity index 100% rename from src/main/webapp/resources/img/logo-header-lodview@2x.png rename to src/main/resources/static/staticResources/img/logo-header-lodview@2x.png diff --git a/src/main/webapp/resources/img/no_image.png b/src/main/resources/static/staticResources/img/no_image.png similarity index 100% rename from src/main/webapp/resources/img/no_image.png rename to src/main/resources/static/staticResources/img/no_image.png diff --git a/src/main/webapp/resources/img/no_image@2x.png b/src/main/resources/static/staticResources/img/no_image@2x.png similarity index 100% rename from src/main/webapp/resources/img/no_image@2x.png rename to src/main/resources/static/staticResources/img/no_image@2x.png diff --git a/src/main/webapp/resources/img/owl404.png b/src/main/resources/static/staticResources/img/owl404.png similarity index 100% rename from src/main/webapp/resources/img/owl404.png rename to src/main/resources/static/staticResources/img/owl404.png diff --git a/src/main/webapp/resources/img/owl404@2x.png b/src/main/resources/static/staticResources/img/owl404@2x.png similarity index 100% rename from src/main/webapp/resources/img/owl404@2x.png rename to src/main/resources/static/staticResources/img/owl404@2x.png diff --git a/src/main/webapp/resources/img/owl500.png b/src/main/resources/static/staticResources/img/owl500.png similarity index 100% rename from src/main/webapp/resources/img/owl500.png rename to src/main/resources/static/staticResources/img/owl500.png diff --git a/src/main/webapp/resources/img/owl500@2x.png b/src/main/resources/static/staticResources/img/owl500@2x.png similarity index 100% rename from src/main/webapp/resources/img/owl500@2x.png rename to src/main/resources/static/staticResources/img/owl500@2x.png diff --git a/src/main/webapp/resources/img/segnaposto-immagine.png b/src/main/resources/static/staticResources/img/segnaposto-immagine.png similarity index 100% rename from src/main/webapp/resources/img/segnaposto-immagine.png rename to src/main/resources/static/staticResources/img/segnaposto-immagine.png diff --git a/src/main/webapp/resources/img/segnaposto-immagine@2x.png b/src/main/resources/static/staticResources/img/segnaposto-immagine@2x.png similarity index 100% rename from src/main/webapp/resources/img/segnaposto-immagine@2x.png rename to src/main/resources/static/staticResources/img/segnaposto-immagine@2x.png diff --git a/src/main/webapp/resources/img/separatoreCorto.png b/src/main/resources/static/staticResources/img/separatoreCorto.png similarity index 100% rename from src/main/webapp/resources/img/separatoreCorto.png rename to src/main/resources/static/staticResources/img/separatoreCorto.png diff --git a/src/main/webapp/resources/img/separatoreCorto@2x.png b/src/main/resources/static/staticResources/img/separatoreCorto@2x.png similarity index 100% rename from src/main/webapp/resources/img/separatoreCorto@2x.png rename to src/main/resources/static/staticResources/img/separatoreCorto@2x.png diff --git a/src/main/resources/static/staticResources/style.css b/src/main/resources/static/staticResources/style.css new file mode 100644 index 0000000..6044476 --- /dev/null +++ b/src/main/resources/static/staticResources/style.css @@ -0,0 +1,7 @@ +@import url('css/reset.css'); +/* first of all, reset! */ +@import url('css/commons.css'); +/* do not touch this */ +@import url('css/commons_2x.css'); +/* pixel ratio > 1 */ +@import url('css/custom.css'); /* your style */ diff --git a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/buffer.png b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/buffer.png similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/circle.skin/buffer.png rename to src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/buffer.png diff --git a/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/circle.player.css b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/circle.player.css new file mode 100644 index 0000000..4437fb2 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/circle.player.css @@ -0,0 +1,144 @@ +/* + * Project: CirclePlayer + * http://www.jplayer.org + * + * Copyright (c) 2011 Happyworm Ltd + * + * Author: Silvia Benvenuti + * Edited by: Mark J Panaghiston + * Date: 6th May 2011 + * Artwork inspired by: http://forrst.com/posts/Untitled-CJz + */ +.cp-jplayer { + display: inline-block +} + +.cp-container { + position: relative; + display: inline-block; + width: 70px; /* 200 - (2 * 48) */ + height: 70px; + background-size: 70px 70px; + padding: 33px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + margin-right: 8px; +} + +.cp-container :focus { + border: none; + outline: 0; +} + +.cp-buffer-1, +.cp-buffer-2, +.cp-progress-1, +.cp-progress-2 { + position: absolute; + top: 0; + left: 0; + width: 70px; + height: 70px; + clip: rect(0px, 35px, 70px, 0px); + + -moz-border-radius: 35px; + -webkit-border-radius: 35px; + border-radius: 35px; +} + +.cp-buffer-1, +.cp-buffer-2 { + /*background: url("buffer.png") 0 0 no-repeat; + background-size:70px 70px;*/ +} + + +/* FALLBACK for .progress + * (24 steps starting from 1hr filled progress, Decrease second value by 104px for next step) + * (It needs the container selector to work. Or use div) + */ + +.cp-container .cp-fallback { + background: url("progress_sprite.png") no-repeat; + background-position: 0 70px; + background-size: 70px 1680px; +} + +.cp-progress-1, +.cp-progress-2 { + background: url("progress.png") 0 0 no-repeat; + background-size: 70px 70px; +} + +.cp-buffer-holder, +.cp-progress-holder, +.cp-circle-control { + position: absolute; + width: 70px; + height: 70px; +} + +.cp-circle-control { + cursor: pointer; +} + +.cp-buffer-holder, +.cp-progress-holder { + clip: rect(0px, 70px, 70px, 35px); + display: none; +} + + +/* This is needed when progress is greater than 50% or for fallback */ + +.cp-buffer-holder.cp-gt50, +.cp-progress-holder.cp-gt50, +.cp-progress.cp-fallback { + clip: rect(auto, auto, auto, auto); +} + +.cp-controls { + margin: 0; + padding: 15px; +} + +.cp-controls li { + list-style-type: none; + display: block; + + /*IE Fix*/ + position: absolute; +} + +.cp-controls li a { + position: relative; + display: block; + width: 40px; + height: 40px; + text-indent: -9999px; + z-index: 1; +} + +.cp-controls .cp-play { + background: url("controls.png") 0 0 no-repeat; + background-size: 80px 80px; +} + +.cp-controls .cp-play:hover { + background: url("controls.png") -40px 0 no-repeat; + background-size: 80px 80px; +} + +.cp-controls .cp-pause { + background: url("controls.png") 0 -40px no-repeat; + background-size: 80px 80px; +} + +.cp-controls .cp-pause:hover { + background: url("controls.png") -40px -40px no-repeat; + background-size: 80px 80px; +} + +.cp-jplayer { + width: 0; + height: 0; +} diff --git a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/controls.png b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/controls.png similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/circle.skin/controls.png rename to src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/controls.png diff --git a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/progress.png b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/progress.png similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/circle.skin/progress.png rename to src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/progress.png diff --git a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/progress_sprite.png b/src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/progress_sprite.png similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/circle.skin/progress_sprite.png rename to src/main/resources/static/staticResources/vendor/jplayercircle/circle.skin/progress_sprite.png diff --git a/src/main/webapp/resources/vendor/jplayercircle/js/Jplayer.swf b/src/main/resources/static/staticResources/vendor/jplayercircle/js/Jplayer.swf similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/js/Jplayer.swf rename to src/main/resources/static/staticResources/vendor/jplayercircle/js/Jplayer.swf diff --git a/src/main/resources/static/staticResources/vendor/jplayercircle/js/circle.player.js b/src/main/resources/static/staticResources/vendor/jplayercircle/js/circle.player.js new file mode 100644 index 0000000..acd90b0 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jplayercircle/js/circle.player.js @@ -0,0 +1,241 @@ +/* + * CirclePlayer for the jPlayer Plugin (jQuery) + * http://www.jplayer.org + * + * Copyright (c) 2009 - 2011 Happyworm Ltd + * Dual licensed under the MIT and GPL licenses. + * - http://www.opensource.org/licenses/mit-license.php + * - http://www.gnu.org/copyleft/gpl.html + * + * Version: 1.0.1 (jPlayer 2.0.9) + * Date: 30th May 2011 + * + * Author: Mark J Panaghiston @thepag + * + * CirclePlayer prototype developed by: + * Mark Boas @maboa + * Silvia Benvenuti @aulentina + * Jussi Kalliokoski @quinirill + * + * Inspired by : + * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt + * and + * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause + * + * Standing on the shoulders of : + * John Resig @jresig + * Mark Panaghiston @thepag + * Louis-Rémi Babé @Louis_Remi + */ + + +var CirclePlayer = function (jPlayerSelector, media, options) { + var self = this, + + defaults = { + // solution: "flash, html", // For testing Flash with CSS3 + supplied: "m4a, oga", + // Android 2.3 corrupts media element if preload:"none" is used. + // preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too. + cssSelectorAncestor: "#cp_container_1", + cssSelector: { + play: ".cp-play", + pause: ".cp-pause" + } + }, + + cssSelector = { + bufferHolder: ".cp-buffer-holder", + buffer1: ".cp-buffer-1", + buffer2: ".cp-buffer-2", + progressHolder: ".cp-progress-holder", + progress1: ".cp-progress-1", + progress2: ".cp-progress-2", + circleControl: ".cp-circle-control" + }; + + this.cssClass = { + gt50: "cp-gt50", + fallback: "cp-fallback" + }; + + this.spritePitch = 104; + this.spriteRatio = 0.24; // Number of steps / 100 + + this.player = $(jPlayerSelector); + this.media = $.extend({}, media); + this.options = $.extend(true, {}, defaults, options); // Deep copy + + this.cssTransforms = Modernizr.csstransforms; + this.audio = {}; + this.dragging = false; // Indicates if the progressbar is being 'dragged'. + + this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy. + + this.jq = {}; + $.each(cssSelector, function (entity, cssSel) { + self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel); + }); + + this._initSolution(); + this._initPlayer(); +}; + +CirclePlayer.prototype = { + _createHtml: function () { + }, + _initPlayer: function () { + var self = this; + this.player.jPlayer(this.options); + + this.player.bind($.jPlayer.event.ready + this.eventNamespace, function (event) { + if (event.jPlayer.html.used && event.jPlayer.html.audio.available) { + self.audio = $(this).data("jPlayer").htmlElement.audio; + } + $(this).jPlayer("setMedia", self.media); + self._initCircleControl(); + }); + + this.player.bind($.jPlayer.event.play + this.eventNamespace, function (event) { + $(this).jPlayer("pauseOthers"); + }); + + // This event fired as play time increments + this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function (event) { + if (!self.dragging) { + self._timeupdate(event.jPlayer.status.currentPercentAbsolute); + } + }); + + // This event fired as buffered time increments + this.player.bind($.jPlayer.event.progress + this.eventNamespace, function (event) { + var percent = 0; + if ((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) { + if (self.audio.duration > 0) { + var bufferTime = 0; + for (var i = 0; i < self.audio.buffered.length; i++) { + bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i); + // console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration); + } + percent = 100 * bufferTime / self.audio.duration; + } // else the Metadata has not been read yet. + // console.log("percent = " + percent); + } else { // Fallback if buffered not supported + // percent = event.jPlayer.status.seekPercent; + percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined. + } + self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill. + // Firefox 4 does not always give the final progress event when buffered = 100% + }); + + this.player.bind($.jPlayer.event.ended + this.eventNamespace, function (event) { + self._resetSolution(); + }); + }, + _initSolution: function () { + if (this.cssTransforms) { + this.jq.progressHolder.show(); + this.jq.bufferHolder.show(); + } else { + this.jq.progressHolder.addClass(this.cssClass.gt50).show(); + this.jq.progress1.addClass(this.cssClass.fallback); + this.jq.progress2.hide(); + this.jq.bufferHolder.hide(); + } + this._resetSolution(); + }, + _resetSolution: function () { + if (this.cssTransforms) { + this.jq.progressHolder.removeClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(0deg)'}); + this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide(); + } else { + this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px'); + } + }, + _initCircleControl: function () { + var self = this; + this.jq.circleControl.grab({ + onstart: function () { + self.dragging = true; + }, onmove: function (event) { + var pc = self._getArcPercent(event.position.x, event.position.y); + self.player.jPlayer("playHead", pc).jPlayer("play"); + self._timeupdate(pc); + }, onfinish: function (event) { + self.dragging = false; + var pc = self._getArcPercent(event.position.x, event.position.y); + self.player.jPlayer("playHead", pc).jPlayer("play"); + } + }); + }, + _timeupdate: function (percent) { + var degs = percent * 3.6 + "deg"; + + var spriteOffset = (Math.floor((Math.round(percent)) * this.spriteRatio) - 1) * -this.spritePitch; + + if (percent <= 50) { + if (this.cssTransforms) { + this.jq.progressHolder.removeClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(' + degs + ')'}); + this.jq.progress2.hide(); + } else { // fall back + this.jq.progress1.css('background-position', '0 ' + spriteOffset + 'px'); + } + } else if (percent <= 100) { + if (this.cssTransforms) { + this.jq.progressHolder.addClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(180deg)'}); + this.jq.progress2.css({'transform': 'rotate(' + degs + ')'}); + this.jq.progress2.show(); + } else { // fall back + this.jq.progress1.css('background-position', '0 ' + spriteOffset + 'px'); + } + } + }, + _progress: function (percent) { + var degs = percent * 3.6 + "deg"; + + if (this.cssTransforms) { + if (percent <= 50) { + this.jq.bufferHolder.removeClass(this.cssClass.gt50); + this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'}); + this.jq.buffer2.hide(); + } else if (percent <= 100) { + this.jq.bufferHolder.addClass(this.cssClass.gt50); + this.jq.buffer1.css({'transform': 'rotate(180deg)'}); + this.jq.buffer2.show(); + this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'}); + } + } + }, + _getArcPercent: function (pageX, pageY) { + var offset = this.jq.circleControl.offset(), + x = pageX - offset.left - this.jq.circleControl.width() / 2, + y = pageY - offset.top - this.jq.circleControl.height() / 2, + theta = Math.atan2(y, x); + + if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) { + theta = 2 * Math.PI + theta; + } + + // theta is now value between -0.5PI and 1.5PI + // ready to be normalized and applied + + return (theta + Math.PI / 2) / 2 * Math.PI * 10; + }, + setMedia: function (media) { + this.media = $.extend({}, media); + this.player.jPlayer("setMedia", this.media); + }, + play: function (time) { + this.player.jPlayer("play", time); + }, + pause: function (time) { + this.player.jPlayer("pause", time); + }, + destroy: function () { + this.player.unbind(this.eventNamespace); + this.player.jPlayer("destroy"); + } +}; diff --git a/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.grab.js b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.grab.js new file mode 100644 index 0000000..2d0e053 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.grab.js @@ -0,0 +1,209 @@ +/* +jQuery grab +https://github.com/jussi-kalliokoski/jQuery.grab +Ported from Jin.js::gestures +https://github.com/jussi-kalliokoski/jin.js/ +Created by Jussi Kalliokoski +Licensed under MIT License. + +Includes fix for IE +*/ + + +(function ($) { + var extend = $.extend, + mousedown = 'mousedown', + mousemove = 'mousemove', + mouseup = 'mouseup', + touchstart = 'touchstart', + touchmove = 'touchmove', + touchend = 'touchend', + touchcancel = 'touchcancel'; + + function unbind(elem, type, func) { + if (type.substr(0, 5) !== 'touch') { // A temporary fix for IE8 data passing problem in Jin. + return $(elem).unbind(type, func); + } + var fnc, i; + for (i = 0; i < bind._binds.length; i++) { + if (bind._binds[i].elem === elem && bind._binds[i].type === type && bind._binds[i].func === func) { + if (document.addEventListener) { + elem.removeEventListener(type, bind._binds[i].fnc, false); + } else { + elem.detachEvent('on' + type, bind._binds[i].fnc); + } + bind._binds.splice(i--, 1); + } + } + } + + function bind(elem, type, func, pass) { + if (type.substr(0, 5) !== 'touch') { // A temporary fix for IE8 data passing problem in Jin. + return $(elem).bind(type, pass, func); + } + var fnc, i; + if (bind[type]) { + return bind[type].bind(elem, type, func, pass); + } + fnc = function (e) { + if (!e) { // Fix some ie bugs... + e = window.event; + } + if (!e.stopPropagation) { + e.stopPropagation = function () { + this.cancelBubble = true; + }; + } + e.data = pass; + func.call(elem, e); + }; + if (document.addEventListener) { + elem.addEventListener(type, fnc, false); + } else { + elem.attachEvent('on' + type, fnc); + } + bind._binds.push({elem: elem, type: type, func: func, fnc: fnc}); + } + + function grab(elem, options) { + var data = { + move: {x: 0, y: 0}, + offset: {x: 0, y: 0}, + position: {x: 0, y: 0}, + start: {x: 0, y: 0}, + affects: document.documentElement, + stopPropagation: false, + preventDefault: true, + touch: true // Implementation unfinished, and doesn't support multitouch + }; + extend(data, options); + data.element = elem; + bind(elem, mousedown, mouseDown, data); + if (data.touch) { + bind(elem, touchstart, touchStart, data); + } + } + + function ungrab(elem) { + unbind(elem, mousedown, mousedown); + } + + function mouseDown(e) { + e.data.position.x = e.pageX; + e.data.position.y = e.pageY; + e.data.start.x = e.pageX; + e.data.start.y = e.pageY; + e.data.event = e; + if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)) { + return; + } + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.stopPropagation) { + e.stopPropagation(); + } + bind(e.data.affects, mousemove, mouseMove, e.data); + bind(e.data.affects, mouseup, mouseUp, e.data); + } + + function mouseMove(e) { + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.preventDefault) { + e.stopPropagation(); + } + e.data.move.x = e.pageX - e.data.position.x; + e.data.move.y = e.pageY - e.data.position.y; + e.data.position.x = e.pageX; + e.data.position.y = e.pageY; + e.data.offset.x = e.pageX - e.data.start.x; + e.data.offset.y = e.pageY - e.data.start.y; + e.data.event = e; + if (e.data.onmove) { + e.data.onmove.call(e.data.element, e.data); + } + } + + function mouseUp(e) { + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.stopPropagation) { + e.stopPropagation(); + } + unbind(e.data.affects, mousemove, mouseMove); + unbind(e.data.affects, mouseup, mouseUp); + e.data.event = e; + if (e.data.onfinish) { + e.data.onfinish.call(e.data.element, e.data); + } + } + + function touchStart(e) { + e.data.position.x = e.touches[0].pageX; + e.data.position.y = e.touches[0].pageY; + e.data.start.x = e.touches[0].pageX; + e.data.start.y = e.touches[0].pageY; + e.data.event = e; + if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)) { + return; + } + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.stopPropagation) { + e.stopPropagation(); + } + bind(e.data.affects, touchmove, touchMove, e.data); + bind(e.data.affects, touchend, touchEnd, e.data); + } + + function touchMove(e) { + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.stopPropagation) { + e.stopPropagation(); + } + e.data.move.x = e.touches[0].pageX - e.data.position.x; + e.data.move.y = e.touches[0].pageY - e.data.position.y; + e.data.position.x = e.touches[0].pageX; + e.data.position.y = e.touches[0].pageY; + e.data.offset.x = e.touches[0].pageX - e.data.start.x; + e.data.offset.y = e.touches[0].pageY - e.data.start.y; + e.data.event = e; + if (e.data.onmove) { + e.data.onmove.call(e.data.elem, e.data); + } + } + + function touchEnd(e) { + if (e.preventDefault && e.data.preventDefault) { + e.preventDefault(); + } + if (e.stopPropagation && e.data.stopPropagation) { + e.stopPropagation(); + } + unbind(e.data.affects, touchmove, touchMove); + unbind(e.data.affects, touchend, touchEnd); + e.data.event = e; + if (e.data.onfinish) { + e.data.onfinish.call(e.data.element, e.data); + } + } + + bind._binds = []; + + $.fn.grab = function (a, b) { + return this.each(function () { + return grab(this, a, b); + }); + }; + $.fn.ungrab = function (a) { + return this.each(function () { + return ungrab(this, a); + }); + }; +})(jQuery); diff --git a/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.jplayer.min.js b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.jplayer.min.js new file mode 100644 index 0000000..99f64d7 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.jplayer.min.js @@ -0,0 +1,3 @@ +/*! jPlayer 2.9.2 for jQuery ~ (c) 2009-2014 Happyworm Ltd ~ MIT License */ +!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b("object"==typeof exports?require("jquery"):a.jQuery?a.jQuery:a.Zepto)}(this,function(a,b){a.fn.jPlayer=function(c){var d="jPlayer",e="string"==typeof c,f=Array.prototype.slice.call(arguments,1),g=this;return c=!e&&f.length?a.extend.apply(null,[!0,c].concat(f)):c,e&&"_"===c.charAt(0)?g:(this.each(e?function(){var e=a(this).data(d),h=e&&a.isFunction(e[c])?e[c].apply(e,f):e;return h!==e&&h!==b?(g=h,!1):void 0}:function(){var b=a(this).data(d);b?b.option(c||{}):a(this).data(d,new a.jPlayer(c,this))}),g)},a.jPlayer=function(b,c){if(arguments.length){this.element=a(c),this.options=a.extend(!0,{},this.options,b);var d=this;this.element.bind("remove.jPlayer",function(){d.destroy()}),this._init()}},"function"!=typeof a.fn.stop&&(a.fn.stop=function(){}),a.jPlayer.emulateMethods="load play pause",a.jPlayer.emulateStatus="src readyState networkState currentTime duration paused ended playbackRate",a.jPlayer.emulateOptions="muted volume",a.jPlayer.reservedEvent="ready flashreset resize repeat error warning",a.jPlayer.event={},a.each(["ready","setmedia","flashreset","resize","repeat","click","error","warning","loadstart","progress","suspend","abort","emptied","stalled","play","pause","loadedmetadata","loadeddata","waiting","playing","canplay","canplaythrough","seeking","seeked","timeupdate","ended","ratechange","durationchange","volumechange"],function(){a.jPlayer.event[this]="jPlayer_"+this}),a.jPlayer.htmlEvent=["loadstart","abort","emptied","stalled","loadedmetadata","canplay","canplaythrough"],a.jPlayer.pause=function(){a.jPlayer.prototype.destroyRemoved(),a.each(a.jPlayer.prototype.instances,function(a,b){b.data("jPlayer").status.srcSet&&b.jPlayer("pause")})},a.jPlayer.timeFormat={showHour:!1,showMin:!0,showSec:!0,padHour:!1,padMin:!0,padSec:!0,sepHour:":",sepMin:":",sepSec:""};var c=function(){this.init()};c.prototype={init:function(){this.options={timeFormat:a.jPlayer.timeFormat}},time:function(a){a=a&&"number"==typeof a?a:0;var b=new Date(1e3*a),c=b.getUTCHours(),d=this.options.timeFormat.showHour?b.getUTCMinutes():b.getUTCMinutes()+60*c,e=this.options.timeFormat.showMin?b.getUTCSeconds():b.getUTCSeconds()+60*d,f=this.options.timeFormat.padHour&&10>c?"0"+c:c,g=this.options.timeFormat.padMin&&10>d?"0"+d:d,h=this.options.timeFormat.padSec&&10>e?"0"+e:e,i="";return i+=this.options.timeFormat.showHour?f+this.options.timeFormat.sepHour:"",i+=this.options.timeFormat.showMin?g+this.options.timeFormat.sepMin:"",i+=this.options.timeFormat.showSec?h+this.options.timeFormat.sepSec:""}};var d=new c;a.jPlayer.convertTime=function(a){return d.time(a)},a.jPlayer.uaBrowser=function(a){var b=a.toLowerCase(),c=/(webkit)[ \/]([\w.]+)/,d=/(opera)(?:.*version)?[ \/]([\w.]+)/,e=/(msie) ([\w.]+)/,f=/(mozilla)(?:.*? rv:([\w.]+))?/,g=c.exec(b)||d.exec(b)||e.exec(b)||b.indexOf("compatible")<0&&f.exec(b)||[];return{browser:g[1]||"",version:g[2]||"0"}},a.jPlayer.uaPlatform=function(a){var b=a.toLowerCase(),c=/(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/,d=/(ipad|playbook)/,e=/(android)/,f=/(mobile)/,g=c.exec(b)||[],h=d.exec(b)||!f.exec(b)&&e.exec(b)||[];return g[1]&&(g[1]=g[1].replace(/\s/g,"_")),{platform:g[1]||"",tablet:h[1]||""}},a.jPlayer.browser={},a.jPlayer.platform={};var e=a.jPlayer.uaBrowser(navigator.userAgent);e.browser&&(a.jPlayer.browser[e.browser]=!0,a.jPlayer.browser.version=e.version);var f=a.jPlayer.uaPlatform(navigator.userAgent);f.platform&&(a.jPlayer.platform[f.platform]=!0,a.jPlayer.platform.mobile=!f.tablet,a.jPlayer.platform.tablet=!!f.tablet),a.jPlayer.getDocMode=function(){var b;return a.jPlayer.browser.msie&&(document.documentMode?b=document.documentMode:(b=5,document.compatMode&&"CSS1Compat"===document.compatMode&&(b=7))),b},a.jPlayer.browser.documentMode=a.jPlayer.getDocMode(),a.jPlayer.nativeFeatures={init:function(){var a,b,c,d=document,e=d.createElement("video"),f={w3c:["fullscreenEnabled","fullscreenElement","requestFullscreen","exitFullscreen","fullscreenchange","fullscreenerror"],moz:["mozFullScreenEnabled","mozFullScreenElement","mozRequestFullScreen","mozCancelFullScreen","mozfullscreenchange","mozfullscreenerror"],webkit:["","webkitCurrentFullScreenElement","webkitRequestFullScreen","webkitCancelFullScreen","webkitfullscreenchange",""],webkitVideo:["webkitSupportsFullscreen","webkitDisplayingFullscreen","webkitEnterFullscreen","webkitExitFullscreen","",""],ms:["","msFullscreenElement","msRequestFullscreen","msExitFullscreen","MSFullscreenChange","MSFullscreenError"]},g=["w3c","moz","webkit","webkitVideo","ms"];for(this.fullscreen=a={support:{w3c:!!d[f.w3c[0]],moz:!!d[f.moz[0]],webkit:"function"==typeof d[f.webkit[3]],webkitVideo:"function"==typeof e[f.webkitVideo[2]],ms:"function"==typeof e[f.ms[2]]},used:{}},b=0,c=g.length;c>b;b++){var h=g[b];if(a.support[h]){a.spec=h,a.used[h]=!0;break}}if(a.spec){var i=f[a.spec];a.api={fullscreenEnabled:!0,fullscreenElement:function(a){return a=a?a:d,a[i[1]]},requestFullscreen:function(a){return a[i[2]]()},exitFullscreen:function(a){return a=a?a:d,a[i[3]]()}},a.event={fullscreenchange:i[4],fullscreenerror:i[5]}}else a.api={fullscreenEnabled:!1,fullscreenElement:function(){return null},requestFullscreen:function(){},exitFullscreen:function(){}},a.event={}}},a.jPlayer.nativeFeatures.init(),a.jPlayer.focus=null,a.jPlayer.keyIgnoreElementNames="A INPUT TEXTAREA SELECT BUTTON";var g=function(b){var c,d=a.jPlayer.focus;d&&(a.each(a.jPlayer.keyIgnoreElementNames.split(/\s+/g),function(a,d){return b.target.nodeName.toUpperCase()===d.toUpperCase()?(c=!0,!1):void 0}),c||a.each(d.options.keyBindings,function(c,e){return e&&a.isFunction(e.fn)&&("number"==typeof e.key&&b.which===e.key||"string"==typeof e.key&&b.key===e.key)?(b.preventDefault(),e.fn(d),!1):void 0}))};a.jPlayer.keys=function(b){var c="keydown.jPlayer";a(document.documentElement).unbind(c),b&&a(document.documentElement).bind(c,g)},a.jPlayer.keys(!0),a.jPlayer.prototype={count:0,version:{script:"2.9.2",needFlash:"2.9.0",flash:"unknown"},options:{swfPath:"js",solution:"html, flash",supplied:"mp3",auroraFormats:"wav",preload:"metadata",volume:.8,muted:!1,remainingDuration:!1,toggleDuration:!1,captureDuration:!0,playbackRate:1,defaultPlaybackRate:1,minPlaybackRate:.5,maxPlaybackRate:4,wmode:"opaque",backgroundColor:"#000000",cssSelectorAncestor:"#jp_container_1",cssSelector:{videoPlay:".jp-video-play",play:".jp-play",pause:".jp-pause",stop:".jp-stop",seekBar:".jp-seek-bar",playBar:".jp-play-bar",mute:".jp-mute",unmute:".jp-unmute",volumeBar:".jp-volume-bar",volumeBarValue:".jp-volume-bar-value",volumeMax:".jp-volume-max",playbackRateBar:".jp-playback-rate-bar",playbackRateBarValue:".jp-playback-rate-bar-value",currentTime:".jp-current-time",duration:".jp-duration",title:".jp-title",fullScreen:".jp-full-screen",restoreScreen:".jp-restore-screen",repeat:".jp-repeat",repeatOff:".jp-repeat-off",gui:".jp-gui",noSolution:".jp-no-solution"},stateClass:{playing:"jp-state-playing",seeking:"jp-state-seeking",muted:"jp-state-muted",looped:"jp-state-looped",fullScreen:"jp-state-full-screen",noVolume:"jp-state-no-volume"},useStateClassSkin:!1,autoBlur:!0,smoothPlayBar:!1,fullScreen:!1,fullWindow:!1,autohide:{restored:!1,full:!0,fadeIn:200,fadeOut:600,hold:1e3},loop:!1,repeat:function(b){b.jPlayer.options.loop?a(this).unbind(".jPlayerRepeat").bind(a.jPlayer.event.ended+".jPlayer.jPlayerRepeat",function(){a(this).jPlayer("play")}):a(this).unbind(".jPlayerRepeat")},nativeVideoControls:{},noFullWindow:{msie:/msie [0-6]\./,ipad:/ipad.*?os [0-4]\./,iphone:/iphone/,ipod:/ipod/,android_pad:/android [0-3]\.(?!.*?mobile)/,android_phone:/(?=.*android)(?!.*chrome)(?=.*mobile)/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/},noVolume:{ipad:/ipad/,iphone:/iphone/,ipod:/ipod/,android_pad:/android(?!.*?mobile)/,android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,iemobile:/iemobile/,webos:/webos/,playbook:/playbook/},timeFormat:{},keyEnabled:!1,audioFullScreen:!1,keyBindings:{play:{key:80,fn:function(a){a.status.paused?a.play():a.pause()}},fullScreen:{key:70,fn:function(a){(a.status.video||a.options.audioFullScreen)&&a._setOption("fullScreen",!a.options.fullScreen)}},muted:{key:77,fn:function(a){a._muted(!a.options.muted)}},volumeUp:{key:190,fn:function(a){a.volume(a.options.volume+.1)}},volumeDown:{key:188,fn:function(a){a.volume(a.options.volume-.1)}},loop:{key:76,fn:function(a){a._loop(!a.options.loop)}}},verticalVolume:!1,verticalPlaybackRate:!1,globalVolume:!1,idPrefix:"jp",noConflict:"jQuery",emulateHtml:!1,consoleAlerts:!0,errorAlerts:!1,warningAlerts:!1},optionsAudio:{size:{width:"0px",height:"0px",cssClass:""},sizeFull:{width:"0px",height:"0px",cssClass:""}},optionsVideo:{size:{width:"480px",height:"270px",cssClass:"jp-video-270p"},sizeFull:{width:"100%",height:"100%",cssClass:"jp-video-full"}},instances:{},status:{src:"",media:{},paused:!0,format:{},formatType:"",waitForPlay:!0,waitForLoad:!0,srcSet:!1,video:!1,seekPercent:0,currentPercentRelative:0,currentPercentAbsolute:0,currentTime:0,duration:0,remaining:0,videoWidth:0,videoHeight:0,readyState:0,networkState:0,playbackRate:1,ended:0},internal:{ready:!1},solution:{html:!0,aurora:!0,flash:!0},format:{mp3:{codec:"audio/mpeg",flashCanPlay:!0,media:"audio"},m4a:{codec:'audio/mp4; codecs="mp4a.40.2"',flashCanPlay:!0,media:"audio"},m3u8a:{codec:'application/vnd.apple.mpegurl; codecs="mp4a.40.2"',flashCanPlay:!1,media:"audio"},m3ua:{codec:"audio/mpegurl",flashCanPlay:!1,media:"audio"},oga:{codec:'audio/ogg; codecs="vorbis, opus"',flashCanPlay:!1,media:"audio"},flac:{codec:"audio/x-flac",flashCanPlay:!1,media:"audio"},wav:{codec:'audio/wav; codecs="1"',flashCanPlay:!1,media:"audio"},webma:{codec:'audio/webm; codecs="vorbis"',flashCanPlay:!1,media:"audio"},fla:{codec:"audio/x-flv",flashCanPlay:!0,media:"audio"},rtmpa:{codec:'audio/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"audio"},m4v:{codec:'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!0,media:"video"},m3u8v:{codec:'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!1,media:"video"},m3uv:{codec:"audio/mpegurl",flashCanPlay:!1,media:"video"},ogv:{codec:'video/ogg; codecs="theora, vorbis"',flashCanPlay:!1,media:"video"},webmv:{codec:'video/webm; codecs="vorbis, vp8"',flashCanPlay:!1,media:"video"},flv:{codec:"video/x-flv",flashCanPlay:!0,media:"video"},rtmpv:{codec:'video/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"video"}},_init:function(){var c=this;if(this.element.empty(),this.status=a.extend({},this.status),this.internal=a.extend({},this.internal),this.options.timeFormat=a.extend({},a.jPlayer.timeFormat,this.options.timeFormat),this.internal.cmdsIgnored=a.jPlayer.platform.ipad||a.jPlayer.platform.iphone||a.jPlayer.platform.ipod,this.internal.domNode=this.element.get(0),this.options.keyEnabled&&!a.jPlayer.focus&&(a.jPlayer.focus=this),this.androidFix={setMedia:!1,play:!1,pause:!1,time:0/0},a.jPlayer.platform.android&&(this.options.preload="auto"!==this.options.preload?"metadata":"auto"),this.formats=[],this.solutions=[],this.require={},this.htmlElement={},this.html={},this.html.audio={},this.html.video={},this.aurora={},this.aurora.formats=[],this.aurora.properties=[],this.flash={},this.css={},this.css.cs={},this.css.jq={},this.ancestorJq=[],this.options.volume=this._limitValue(this.options.volume,0,1),a.each(this.options.supplied.toLowerCase().split(","),function(b,d){var e=d.replace(/^\s+|\s+$/g,"");if(c.format[e]){var f=!1;a.each(c.formats,function(a,b){return e===b?(f=!0,!1):void 0}),f||c.formats.push(e)}}),a.each(this.options.solution.toLowerCase().split(","),function(b,d){var e=d.replace(/^\s+|\s+$/g,"");if(c.solution[e]){var f=!1;a.each(c.solutions,function(a,b){return e===b?(f=!0,!1):void 0}),f||c.solutions.push(e)}}),a.each(this.options.auroraFormats.toLowerCase().split(","),function(b,d){var e=d.replace(/^\s+|\s+$/g,"");if(c.format[e]){var f=!1;a.each(c.aurora.formats,function(a,b){return e===b?(f=!0,!1):void 0}),f||c.aurora.formats.push(e)}}),this.internal.instance="jp_"+this.count,this.instances[this.internal.instance]=this.element,this.element.attr("id")||this.element.attr("id",this.options.idPrefix+"_jplayer_"+this.count),this.internal.self=a.extend({},{id:this.element.attr("id"),jq:this.element}),this.internal.audio=a.extend({},{id:this.options.idPrefix+"_audio_"+this.count,jq:b}),this.internal.video=a.extend({},{id:this.options.idPrefix+"_video_"+this.count,jq:b}),this.internal.flash=a.extend({},{id:this.options.idPrefix+"_flash_"+this.count,jq:b,swf:this.options.swfPath+(".swf"!==this.options.swfPath.toLowerCase().slice(-4)?(this.options.swfPath&&"/"!==this.options.swfPath.slice(-1)?"/":"")+"jquery.jplayer.swf":"")}),this.internal.poster=a.extend({},{id:this.options.idPrefix+"_poster_"+this.count,jq:b}),a.each(a.jPlayer.event,function(a,d){c.options[a]!==b&&(c.element.bind(d+".jPlayer",c.options[a]),c.options[a]=b)}),this.require.audio=!1,this.require.video=!1,a.each(this.formats,function(a,b){c.require[c.format[b].media]=!0}),this.options=this.require.video?a.extend(!0,{},this.optionsVideo,this.options):a.extend(!0,{},this.optionsAudio,this.options),this._setSize(),this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls),this.status.noFullWindow=this._uaBlocklist(this.options.noFullWindow),this.status.noVolume=this._uaBlocklist(this.options.noVolume),a.jPlayer.nativeFeatures.fullscreen.api.fullscreenEnabled&&this._fullscreenAddEventListeners(),this._restrictNativeVideoControls(),this.htmlElement.poster=document.createElement("img"),this.htmlElement.poster.id=this.internal.poster.id,this.htmlElement.poster.onload=function(){(!c.status.video||c.status.waitForPlay)&&c.internal.poster.jq.show()},this.element.append(this.htmlElement.poster),this.internal.poster.jq=a("#"+this.internal.poster.id),this.internal.poster.jq.css({width:this.status.width,height:this.status.height}),this.internal.poster.jq.hide(),this.internal.poster.jq.bind("click.jPlayer",function(){c._trigger(a.jPlayer.event.click)}),this.html.audio.available=!1,this.require.audio&&(this.htmlElement.audio=document.createElement("audio"),this.htmlElement.audio.id=this.internal.audio.id,this.html.audio.available=!!this.htmlElement.audio.canPlayType&&this._testCanPlayType(this.htmlElement.audio)),this.html.video.available=!1,this.require.video&&(this.htmlElement.video=document.createElement("video"),this.htmlElement.video.id=this.internal.video.id,this.html.video.available=!!this.htmlElement.video.canPlayType&&this._testCanPlayType(this.htmlElement.video)),this.flash.available=this._checkForFlash(10.1),this.html.canPlay={},this.aurora.canPlay={},this.flash.canPlay={},a.each(this.formats,function(b,d){c.html.canPlay[d]=c.html[c.format[d].media].available&&""!==c.htmlElement[c.format[d].media].canPlayType(c.format[d].codec),c.aurora.canPlay[d]=a.inArray(d,c.aurora.formats)>-1,c.flash.canPlay[d]=c.format[d].flashCanPlay&&c.flash.available}),this.html.desired=!1,this.aurora.desired=!1,this.flash.desired=!1,a.each(this.solutions,function(b,d){if(0===b)c[d].desired=!0;else{var e=!1,f=!1;a.each(c.formats,function(a,b){c[c.solutions[0]].canPlay[b]&&("video"===c.format[b].media?f=!0:e=!0)}),c[d].desired=c.require.audio&&!e||c.require.video&&!f}}),this.html.support={},this.aurora.support={},this.flash.support={},a.each(this.formats,function(a,b){c.html.support[b]=c.html.canPlay[b]&&c.html.desired,c.aurora.support[b]=c.aurora.canPlay[b]&&c.aurora.desired,c.flash.support[b]=c.flash.canPlay[b]&&c.flash.desired}),this.html.used=!1,this.aurora.used=!1,this.flash.used=!1,a.each(this.solutions,function(b,d){a.each(c.formats,function(a,b){return c[d].support[b]?(c[d].used=!0,!1):void 0})}),this._resetActive(),this._resetGate(),this._cssSelectorAncestor(this.options.cssSelectorAncestor),this.html.used||this.aurora.used||this.flash.used?this.css.jq.noSolution.length&&this.css.jq.noSolution.hide():(this._error({type:a.jPlayer.error.NO_SOLUTION,context:"{solution:'"+this.options.solution+"', supplied:'"+this.options.supplied+"'}",message:a.jPlayer.errorMsg.NO_SOLUTION,hint:a.jPlayer.errorHint.NO_SOLUTION}),this.css.jq.noSolution.length&&this.css.jq.noSolution.show()),this.flash.used){var d,e="jQuery="+encodeURI(this.options.noConflict)+"&id="+encodeURI(this.internal.self.id)+"&vol="+this.options.volume+"&muted="+this.options.muted;if(a.jPlayer.browser.msie&&(Number(a.jPlayer.browser.version)<9||a.jPlayer.browser.documentMode<9)){var f='',g=['','','','',''];d=document.createElement(f);for(var h=0;h0&&(d.internal.cmdsIgnored=!1),d._getHtmlStatus(b),d._updateInterface(),d._trigger(a.jPlayer.event.progress))},!1),b.addEventListener("loadeddata",function(){c.gate&&(d.androidFix.setMedia=!1,d.androidFix.play&&(d.androidFix.play=!1,d.play(d.androidFix.time)),d.androidFix.pause&&(d.androidFix.pause=!1,d.pause(d.androidFix.time)),d._trigger(a.jPlayer.event.loadeddata))},!1),b.addEventListener("timeupdate",function(){c.gate&&(d._getHtmlStatus(b),d._updateInterface(),d._trigger(a.jPlayer.event.timeupdate))},!1),b.addEventListener("durationchange",function(){c.gate&&(d._getHtmlStatus(b),d._updateInterface(),d._trigger(a.jPlayer.event.durationchange))},!1),b.addEventListener("play",function(){c.gate&&(d._updateButtons(!0),d._html_checkWaitForPlay(),d._trigger(a.jPlayer.event.play))},!1),b.addEventListener("playing",function(){c.gate&&(d._updateButtons(!0),d._seeked(),d._trigger(a.jPlayer.event.playing))},!1),b.addEventListener("pause",function(){c.gate&&(d._updateButtons(!1),d._trigger(a.jPlayer.event.pause))},!1),b.addEventListener("waiting",function(){c.gate&&(d._seeking(),d._trigger(a.jPlayer.event.waiting))},!1),b.addEventListener("seeking",function(){c.gate&&(d._seeking(),d._trigger(a.jPlayer.event.seeking))},!1),b.addEventListener("seeked",function(){c.gate&&(d._seeked(),d._trigger(a.jPlayer.event.seeked))},!1),b.addEventListener("volumechange",function(){c.gate&&(d.options.volume=b.volume,d.options.muted=b.muted,d._updateMute(),d._updateVolume(),d._trigger(a.jPlayer.event.volumechange))},!1),b.addEventListener("ratechange",function(){c.gate&&(d.options.defaultPlaybackRate=b.defaultPlaybackRate,d.options.playbackRate=b.playbackRate,d._updatePlaybackRate(),d._trigger(a.jPlayer.event.ratechange))},!1),b.addEventListener("suspend",function(){c.gate&&(d._seeked(),d._trigger(a.jPlayer.event.suspend))},!1),b.addEventListener("ended",function(){c.gate&&(a.jPlayer.browser.webkit||(d.htmlElement.media.currentTime=0),d.htmlElement.media.pause(),d._updateButtons(!1),d._getHtmlStatus(b,!0),d._updateInterface(),d._trigger(a.jPlayer.event.ended))},!1),b.addEventListener("error",function(){c.gate&&(d._updateButtons(!1),d._seeked(),d.status.srcSet&&(clearTimeout(d.internal.htmlDlyCmdId),d.status.waitForLoad=!0,d.status.waitForPlay=!0,d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"}),d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show(),d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show(),d._error({type:a.jPlayer.error.URL,context:d.status.src,message:a.jPlayer.errorMsg.URL,hint:a.jPlayer.errorHint.URL})))},!1),a.each(a.jPlayer.htmlEvent,function(e,f){b.addEventListener(this,function(){c.gate&&d._trigger(a.jPlayer.event[f])},!1)})},_addAuroraEventListeners:function(b,c){var d=this;b.volume=100*this.options.volume,b.on("progress",function(){c.gate&&(d.internal.cmdsIgnored&&this.readyState>0&&(d.internal.cmdsIgnored=!1),d._getAuroraStatus(b),d._updateInterface(),d._trigger(a.jPlayer.event.progress),b.duration>0&&d._trigger(a.jPlayer.event.timeupdate))},!1),b.on("ready",function(){c.gate&&d._trigger(a.jPlayer.event.loadeddata)},!1),b.on("duration",function(){c.gate&&(d._getAuroraStatus(b),d._updateInterface(),d._trigger(a.jPlayer.event.durationchange))},!1),b.on("end",function(){c.gate&&(d._updateButtons(!1),d._getAuroraStatus(b,!0),d._updateInterface(),d._trigger(a.jPlayer.event.ended))},!1),b.on("error",function(){c.gate&&(d._updateButtons(!1),d._seeked(),d.status.srcSet&&(d.status.waitForLoad=!0,d.status.waitForPlay=!0,d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"}),d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show(),d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show(),d._error({type:a.jPlayer.error.URL,context:d.status.src,message:a.jPlayer.errorMsg.URL,hint:a.jPlayer.errorHint.URL})))},!1)},_getHtmlStatus:function(a,b){var c=0,d=0,e=0,f=0;isFinite(a.duration)&&(this.status.duration=a.duration),c=a.currentTime,d=this.status.duration>0?100*c/this.status.duration:0,"object"==typeof a.seekable&&a.seekable.length>0?(e=this.status.duration>0?100*a.seekable.end(a.seekable.length-1)/this.status.duration:100,f=this.status.duration>0?100*a.currentTime/a.seekable.end(a.seekable.length-1):0):(e=100,f=d),b&&(c=0,f=0,d=0),this.status.seekPercent=e,this.status.currentPercentRelative=f,this.status.currentPercentAbsolute=d,this.status.currentTime=c,this.status.remaining=this.status.duration-this.status.currentTime,this.status.videoWidth=a.videoWidth,this.status.videoHeight=a.videoHeight,this.status.readyState=a.readyState,this.status.networkState=a.networkState,this.status.playbackRate=a.playbackRate,this.status.ended=a.ended},_getAuroraStatus:function(a,b){var c=0,d=0,e=0,f=0;this.status.duration=a.duration/1e3,c=a.currentTime/1e3,d=this.status.duration>0?100*c/this.status.duration:0,a.buffered>0?(e=this.status.duration>0?a.buffered*this.status.duration/this.status.duration:100,f=this.status.duration>0?c/(a.buffered*this.status.duration):0):(e=100,f=d),b&&(c=0,f=0,d=0),this.status.seekPercent=e,this.status.currentPercentRelative=f,this.status.currentPercentAbsolute=d,this.status.currentTime=c,this.status.remaining=this.status.duration-this.status.currentTime,this.status.readyState=4,this.status.networkState=0,this.status.playbackRate=1,this.status.ended=!1},_resetStatus:function(){this.status=a.extend({},this.status,a.jPlayer.prototype.status)},_trigger:function(b,c,d){var e=a.Event(b);e.jPlayer={},e.jPlayer.version=a.extend({},this.version),e.jPlayer.options=a.extend(!0,{},this.options),e.jPlayer.status=a.extend(!0,{},this.status),e.jPlayer.html=a.extend(!0,{},this.html),e.jPlayer.aurora=a.extend(!0,{},this.aurora),e.jPlayer.flash=a.extend(!0,{},this.flash),c&&(e.jPlayer.error=a.extend({},c)),d&&(e.jPlayer.warning=a.extend({},d)),this.element.trigger(e)},jPlayerFlashEvent:function(b,c){if(b===a.jPlayer.event.ready)if(this.internal.ready){if(this.flash.gate){if(this.status.srcSet){var d=this.status.currentTime,e=this.status.paused;this.setMedia(this.status.media),this.volumeWorker(this.options.volume),d>0&&(e?this.pause(d):this.play(d))}this._trigger(a.jPlayer.event.flashreset)}}else this.internal.ready=!0,this.internal.flash.jq.css({width:"0px",height:"0px"}),this.version.flash=c.version,this.version.needFlash!==this.version.flash&&this._error({type:a.jPlayer.error.VERSION,context:this.version.flash,message:a.jPlayer.errorMsg.VERSION+this.version.flash,hint:a.jPlayer.errorHint.VERSION}),this._trigger(a.jPlayer.event.repeat),this._trigger(b);if(this.flash.gate)switch(b){case a.jPlayer.event.progress:this._getFlashStatus(c),this._updateInterface(),this._trigger(b);break;case a.jPlayer.event.timeupdate:this._getFlashStatus(c),this._updateInterface(),this._trigger(b);break;case a.jPlayer.event.play:this._seeked(),this._updateButtons(!0),this._trigger(b);break;case a.jPlayer.event.pause:this._updateButtons(!1),this._trigger(b);break;case a.jPlayer.event.ended:this._updateButtons(!1),this._trigger(b);break;case a.jPlayer.event.click:this._trigger(b);break;case a.jPlayer.event.error:this.status.waitForLoad=!0,this.status.waitForPlay=!0,this.status.video&&this.internal.flash.jq.css({width:"0px",height:"0px"}),this._validString(this.status.media.poster)&&this.internal.poster.jq.show(),this.css.jq.videoPlay.length&&this.status.video&&this.css.jq.videoPlay.show(),this.status.video?this._flash_setVideo(this.status.media):this._flash_setAudio(this.status.media),this._updateButtons(!1),this._error({type:a.jPlayer.error.URL,context:c.src,message:a.jPlayer.errorMsg.URL,hint:a.jPlayer.errorHint.URL});break;case a.jPlayer.event.seeking:this._seeking(),this._trigger(b);break;case a.jPlayer.event.seeked:this._seeked(),this._trigger(b);break;case a.jPlayer.event.ready:break;default:this._trigger(b)}return!1},_getFlashStatus:function(a){this.status.seekPercent=a.seekPercent,this.status.currentPercentRelative=a.currentPercentRelative,this.status.currentPercentAbsolute=a.currentPercentAbsolute,this.status.currentTime=a.currentTime,this.status.duration=a.duration,this.status.remaining=a.duration-a.currentTime,this.status.videoWidth=a.videoWidth,this.status.videoHeight=a.videoHeight,this.status.readyState=4,this.status.networkState=0,this.status.playbackRate=1,this.status.ended=!1},_updateButtons:function(a){a===b?a=!this.status.paused:this.status.paused=!a,a?this.addStateClass("playing"):this.removeStateClass("playing"),!this.status.noFullWindow&&this.options.fullWindow?this.addStateClass("fullScreen"):this.removeStateClass("fullScreen"),this.options.loop?this.addStateClass("looped"):this.removeStateClass("looped"),this.css.jq.play.length&&this.css.jq.pause.length&&(a?(this.css.jq.play.hide(),this.css.jq.pause.show()):(this.css.jq.play.show(),this.css.jq.pause.hide())),this.css.jq.restoreScreen.length&&this.css.jq.fullScreen.length&&(this.status.noFullWindow?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.hide()):this.options.fullWindow?(this.css.jq.fullScreen.hide(),this.css.jq.restoreScreen.show()):(this.css.jq.fullScreen.show(),this.css.jq.restoreScreen.hide())),this.css.jq.repeat.length&&this.css.jq.repeatOff.length&&(this.options.loop?(this.css.jq.repeat.hide(),this.css.jq.repeatOff.show()):(this.css.jq.repeat.show(),this.css.jq.repeatOff.hide()))},_updateInterface:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.width(this.status.seekPercent+"%"),this.css.jq.playBar.length&&(this.options.smoothPlayBar?this.css.jq.playBar.stop().animate({width:this.status.currentPercentAbsolute+"%"},250,"linear"):this.css.jq.playBar.width(this.status.currentPercentRelative+"%"));var a="";this.css.jq.currentTime.length&&(a=this._convertTime(this.status.currentTime),a!==this.css.jq.currentTime.text()&&this.css.jq.currentTime.text(this._convertTime(this.status.currentTime)));var b="",c=this.status.duration,d=this.status.remaining;this.css.jq.duration.length&&("string"==typeof this.status.media.duration?b=this.status.media.duration:("number"==typeof this.status.media.duration&&(c=this.status.media.duration,d=c-this.status.currentTime),b=this.options.remainingDuration?(d>0?"-":"")+this._convertTime(d):this._convertTime(c)),b!==this.css.jq.duration.text()&&this.css.jq.duration.text(b))},_convertTime:c.prototype.time,_seeking:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.addClass("jp-seeking-bg"),this.addStateClass("seeking")},_seeked:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.removeClass("jp-seeking-bg"),this.removeStateClass("seeking")},_resetGate:function(){this.html.audio.gate=!1,this.html.video.gate=!1,this.aurora.gate=!1,this.flash.gate=!1},_resetActive:function(){this.html.active=!1,this.aurora.active=!1,this.flash.active=!1},_escapeHtml:function(a){return a.split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""")},_qualifyURL:function(a){var b=document.createElement("div"); +return b.innerHTML='x',b.firstChild.href},_absoluteMediaUrls:function(b){var c=this;return a.each(b,function(a,d){d&&c.format[a]&&"data:"!==d.substr(0,5)&&(b[a]=c._qualifyURL(d))}),b},addStateClass:function(a){this.ancestorJq.length&&this.ancestorJq.addClass(this.options.stateClass[a])},removeStateClass:function(a){this.ancestorJq.length&&this.ancestorJq.removeClass(this.options.stateClass[a])},setMedia:function(b){var c=this,d=!1,e=this.status.media.poster!==b.poster;this._resetMedia(),this._resetGate(),this._resetActive(),this.androidFix.setMedia=!1,this.androidFix.play=!1,this.androidFix.pause=!1,b=this._absoluteMediaUrls(b),a.each(this.formats,function(e,f){var g="video"===c.format[f].media;return a.each(c.solutions,function(e,h){if(c[h].support[f]&&c._validString(b[f])){var i="html"===h,j="aurora"===h;return g?(i?(c.html.video.gate=!0,c._html_setVideo(b),c.html.active=!0):(c.flash.gate=!0,c._flash_setVideo(b),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.show(),c.status.video=!0):(i?(c.html.audio.gate=!0,c._html_setAudio(b),c.html.active=!0,a.jPlayer.platform.android&&(c.androidFix.setMedia=!0)):j?(c.aurora.gate=!0,c._aurora_setAudio(b),c.aurora.active=!0):(c.flash.gate=!0,c._flash_setAudio(b),c.flash.active=!0),c.css.jq.videoPlay.length&&c.css.jq.videoPlay.hide(),c.status.video=!1),d=!0,!1}}),d?!1:void 0}),d?(this.status.nativeVideoControls&&this.html.video.gate||this._validString(b.poster)&&(e?this.htmlElement.poster.src=b.poster:this.internal.poster.jq.show()),"string"==typeof b.title&&(this.css.jq.title.length&&this.css.jq.title.html(b.title),this.htmlElement.audio&&this.htmlElement.audio.setAttribute("title",b.title),this.htmlElement.video&&this.htmlElement.video.setAttribute("title",b.title)),this.status.srcSet=!0,this.status.media=a.extend({},b),this._updateButtons(!1),this._updateInterface(),this._trigger(a.jPlayer.event.setmedia)):this._error({type:a.jPlayer.error.NO_SUPPORT,context:"{supplied:'"+this.options.supplied+"'}",message:a.jPlayer.errorMsg.NO_SUPPORT,hint:a.jPlayer.errorHint.NO_SUPPORT})},_resetMedia:function(){this._resetStatus(),this._updateButtons(!1),this._updateInterface(),this._seeked(),this.internal.poster.jq.hide(),clearTimeout(this.internal.htmlDlyCmdId),this.html.active?this._html_resetMedia():this.aurora.active?this._aurora_resetMedia():this.flash.active&&this._flash_resetMedia()},clearMedia:function(){this._resetMedia(),this.html.active?this._html_clearMedia():this.aurora.active?this._aurora_clearMedia():this.flash.active&&this._flash_clearMedia(),this._resetGate(),this._resetActive()},load:function(){this.status.srcSet?this.html.active?this._html_load():this.aurora.active?this._aurora_load():this.flash.active&&this._flash_load():this._urlNotSetError("load")},focus:function(){this.options.keyEnabled&&(a.jPlayer.focus=this)},play:function(a){var b="object"==typeof a;b&&this.options.useStateClassSkin&&!this.status.paused?this.pause(a):(a="number"==typeof a?a:0/0,this.status.srcSet?(this.focus(),this.html.active?this._html_play(a):this.aurora.active?this._aurora_play(a):this.flash.active&&this._flash_play(a)):this._urlNotSetError("play"))},videoPlay:function(){this.play()},pause:function(a){a="number"==typeof a?a:0/0,this.status.srcSet?this.html.active?this._html_pause(a):this.aurora.active?this._aurora_pause(a):this.flash.active&&this._flash_pause(a):this._urlNotSetError("pause")},tellOthers:function(b,c){var d=this,e="function"==typeof c,f=Array.prototype.slice.call(arguments);"string"==typeof b&&(e&&f.splice(1,1),a.jPlayer.prototype.destroyRemoved(),a.each(this.instances,function(){d.element!==this&&(!e||c.call(this.data("jPlayer"),d))&&this.jPlayer.apply(this,f)}))},pauseOthers:function(a){this.tellOthers("pause",function(){return this.status.srcSet},a)},stop:function(){this.status.srcSet?this.html.active?this._html_pause(0):this.aurora.active?this._aurora_pause(0):this.flash.active&&this._flash_pause(0):this._urlNotSetError("stop")},playHead:function(a){a=this._limitValue(a,0,100),this.status.srcSet?this.html.active?this._html_playHead(a):this.aurora.active?this._aurora_playHead(a):this.flash.active&&this._flash_playHead(a):this._urlNotSetError("playHead")},_muted:function(a){this.mutedWorker(a),this.options.globalVolume&&this.tellOthers("mutedWorker",function(){return this.options.globalVolume},a)},mutedWorker:function(b){this.options.muted=b,this.html.used&&this._html_setProperty("muted",b),this.aurora.used&&this._aurora_mute(b),this.flash.used&&this._flash_mute(b),this.html.video.gate||this.html.audio.gate||(this._updateMute(b),this._updateVolume(this.options.volume),this._trigger(a.jPlayer.event.volumechange))},mute:function(a){var c="object"==typeof a;c&&this.options.useStateClassSkin&&this.options.muted?this._muted(!1):(a=a===b?!0:!!a,this._muted(a))},unmute:function(a){a=a===b?!0:!!a,this._muted(!a)},_updateMute:function(a){a===b&&(a=this.options.muted),a?this.addStateClass("muted"):this.removeStateClass("muted"),this.css.jq.mute.length&&this.css.jq.unmute.length&&(this.status.noVolume?(this.css.jq.mute.hide(),this.css.jq.unmute.hide()):a?(this.css.jq.mute.hide(),this.css.jq.unmute.show()):(this.css.jq.mute.show(),this.css.jq.unmute.hide()))},volume:function(a){this.volumeWorker(a),this.options.globalVolume&&this.tellOthers("volumeWorker",function(){return this.options.globalVolume},a)},volumeWorker:function(b){b=this._limitValue(b,0,1),this.options.volume=b,this.html.used&&this._html_setProperty("volume",b),this.aurora.used&&this._aurora_volume(b),this.flash.used&&this._flash_volume(b),this.html.video.gate||this.html.audio.gate||(this._updateVolume(b),this._trigger(a.jPlayer.event.volumechange))},volumeBar:function(b){if(this.css.jq.volumeBar.length){var c=a(b.currentTarget),d=c.offset(),e=b.pageX-d.left,f=c.width(),g=c.height()-b.pageY+d.top,h=c.height();this.volume(this.options.verticalVolume?g/h:e/f)}this.options.muted&&this._muted(!1)},_updateVolume:function(a){a===b&&(a=this.options.volume),a=this.options.muted?0:a,this.status.noVolume?(this.addStateClass("noVolume"),this.css.jq.volumeBar.length&&this.css.jq.volumeBar.hide(),this.css.jq.volumeBarValue.length&&this.css.jq.volumeBarValue.hide(),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.hide()):(this.removeStateClass("noVolume"),this.css.jq.volumeBar.length&&this.css.jq.volumeBar.show(),this.css.jq.volumeBarValue.length&&(this.css.jq.volumeBarValue.show(),this.css.jq.volumeBarValue[this.options.verticalVolume?"height":"width"](100*a+"%")),this.css.jq.volumeMax.length&&this.css.jq.volumeMax.show())},volumeMax:function(){this.volume(1),this.options.muted&&this._muted(!1)},_cssSelectorAncestor:function(b){var c=this;this.options.cssSelectorAncestor=b,this._removeUiClass(),this.ancestorJq=b?a(b):[],b&&1!==this.ancestorJq.length&&this._warning({type:a.jPlayer.warning.CSS_SELECTOR_COUNT,context:b,message:a.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.ancestorJq.length+" found for cssSelectorAncestor.",hint:a.jPlayer.warningHint.CSS_SELECTOR_COUNT}),this._addUiClass(),a.each(this.options.cssSelector,function(a,b){c._cssSelector(a,b)}),this._updateInterface(),this._updateButtons(),this._updateAutohide(),this._updateVolume(),this._updateMute()},_cssSelector:function(b,c){var d=this;if("string"==typeof c)if(a.jPlayer.prototype.options.cssSelector[b]){if(this.css.jq[b]&&this.css.jq[b].length&&this.css.jq[b].unbind(".jPlayer"),this.options.cssSelector[b]=c,this.css.cs[b]=this.options.cssSelectorAncestor+" "+c,this.css.jq[b]=c?a(this.css.cs[b]):[],this.css.jq[b].length&&this[b]){var e=function(c){c.preventDefault(),d[b](c),d.options.autoBlur?a(this).blur():a(this).focus()};this.css.jq[b].bind("click.jPlayer",e)}c&&1!==this.css.jq[b].length&&this._warning({type:a.jPlayer.warning.CSS_SELECTOR_COUNT,context:this.css.cs[b],message:a.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.css.jq[b].length+" found for "+b+" method.",hint:a.jPlayer.warningHint.CSS_SELECTOR_COUNT})}else this._warning({type:a.jPlayer.warning.CSS_SELECTOR_METHOD,context:b,message:a.jPlayer.warningMsg.CSS_SELECTOR_METHOD,hint:a.jPlayer.warningHint.CSS_SELECTOR_METHOD});else this._warning({type:a.jPlayer.warning.CSS_SELECTOR_STRING,context:c,message:a.jPlayer.warningMsg.CSS_SELECTOR_STRING,hint:a.jPlayer.warningHint.CSS_SELECTOR_STRING})},duration:function(a){this.options.toggleDuration&&(this.options.captureDuration&&a.stopPropagation(),this._setOption("remainingDuration",!this.options.remainingDuration))},seekBar:function(b){if(this.css.jq.seekBar.length){var c=a(b.currentTarget),d=c.offset(),e=b.pageX-d.left,f=c.width(),g=100*e/f;this.playHead(g)}},playbackRate:function(a){this._setOption("playbackRate",a)},playbackRateBar:function(b){if(this.css.jq.playbackRateBar.length){var c,d,e=a(b.currentTarget),f=e.offset(),g=b.pageX-f.left,h=e.width(),i=e.height()-b.pageY+f.top,j=e.height();c=this.options.verticalPlaybackRate?i/j:g/h,d=c*(this.options.maxPlaybackRate-this.options.minPlaybackRate)+this.options.minPlaybackRate,this.playbackRate(d)}},_updatePlaybackRate:function(){var a=this.options.playbackRate,b=(a-this.options.minPlaybackRate)/(this.options.maxPlaybackRate-this.options.minPlaybackRate);this.status.playbackRateEnabled?(this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.show(),this.css.jq.playbackRateBarValue.length&&(this.css.jq.playbackRateBarValue.show(),this.css.jq.playbackRateBarValue[this.options.verticalPlaybackRate?"height":"width"](100*b+"%"))):(this.css.jq.playbackRateBar.length&&this.css.jq.playbackRateBar.hide(),this.css.jq.playbackRateBarValue.length&&this.css.jq.playbackRateBarValue.hide())},repeat:function(a){var b="object"==typeof a;this._loop(b&&this.options.useStateClassSkin&&this.options.loop?!1:!0)},repeatOff:function(){this._loop(!1)},_loop:function(b){this.options.loop!==b&&(this.options.loop=b,this._updateButtons(),this._trigger(a.jPlayer.event.repeat))},option:function(c,d){var e=c;if(0===arguments.length)return a.extend(!0,{},this.options);if("string"==typeof c){var f=c.split(".");if(d===b){for(var g=a.extend(!0,{},this.options),h=0;h0||Math.floor(d)>0):e=!0,a.internal.mouse={x:b.pageX,y:b.pageY},e&&a.css.jq.gui.fadeIn(a.options.autohide.fadeIn,function(){clearTimeout(a.internal.autohideId),a.internal.autohideId=setTimeout(function(){a.css.jq.gui.fadeOut(a.options.autohide.fadeOut)},a.options.autohide.hold)})};this.css.jq.gui.length&&(this.css.jq.gui.stop(!0,!0),clearTimeout(this.internal.autohideId),delete this.internal.mouse,this.element.unbind(c),this.css.jq.gui.unbind(c),this.status.nativeVideoControls?this.css.jq.gui.hide():this.options.fullWindow&&this.options.autohide.full||!this.options.fullWindow&&this.options.autohide.restored?(this.element.bind(d,e),this.css.jq.gui.bind(d,e),this.css.jq.gui.hide()):this.css.jq.gui.show())},fullScreen:function(a){var b="object"==typeof a;b&&this.options.useStateClassSkin&&this.options.fullScreen?this._setOption("fullScreen",!1):this._setOption("fullScreen",!0)},restoreScreen:function(){this._setOption("fullScreen",!1)},_fullscreenAddEventListeners:function(){var b=this,c=a.jPlayer.nativeFeatures.fullscreen;c.api.fullscreenEnabled&&c.event.fullscreenchange&&("function"!=typeof this.internal.fullscreenchangeHandler&&(this.internal.fullscreenchangeHandler=function(){b._fullscreenchange()}),document.addEventListener(c.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1))},_fullscreenRemoveEventListeners:function(){var b=a.jPlayer.nativeFeatures.fullscreen;this.internal.fullscreenchangeHandler&&document.removeEventListener(b.event.fullscreenchange,this.internal.fullscreenchangeHandler,!1)},_fullscreenchange:function(){this.options.fullScreen&&!a.jPlayer.nativeFeatures.fullscreen.api.fullscreenElement()&&this._setOption("fullScreen",!1)},_requestFullscreen:function(){var b=this.ancestorJq.length?this.ancestorJq[0]:this.element[0],c=a.jPlayer.nativeFeatures.fullscreen;c.used.webkitVideo&&(b=this.htmlElement.video),c.api.fullscreenEnabled&&c.api.requestFullscreen(b)},_exitFullscreen:function(){var b,c=a.jPlayer.nativeFeatures.fullscreen;c.used.webkitVideo&&(b=this.htmlElement.video),c.api.fullscreenEnabled&&c.api.exitFullscreen(b)},_html_initMedia:function(b){var c=a(this.htmlElement.media).empty();a.each(b.track||[],function(a,b){var d=document.createElement("track");d.setAttribute("kind",b.kind?b.kind:""),d.setAttribute("src",b.src?b.src:""),d.setAttribute("srclang",b.srclang?b.srclang:""),d.setAttribute("label",b.label?b.label:""),b.def&&d.setAttribute("default",b.def),c.append(d)}),this.htmlElement.media.src=this.status.src,"none"!==this.options.preload&&this._html_load(),this._trigger(a.jPlayer.event.timeupdate)},_html_setFormat:function(b){var c=this;a.each(this.formats,function(a,d){return c.html.support[d]&&b[d]?(c.status.src=b[d],c.status.format[d]=!0,c.status.formatType=d,!1):void 0})},_html_setAudio:function(a){this._html_setFormat(a),this.htmlElement.media=this.htmlElement.audio,this._html_initMedia(a)},_html_setVideo:function(a){this._html_setFormat(a),this.status.nativeVideoControls&&(this.htmlElement.video.poster=this._validString(a.poster)?a.poster:""),this.htmlElement.media=this.htmlElement.video,this._html_initMedia(a)},_html_resetMedia:function(){this.htmlElement.media&&(this.htmlElement.media.id!==this.internal.video.id||this.status.nativeVideoControls||this.internal.video.jq.css({width:"0px",height:"0px"}),this.htmlElement.media.pause())},_html_clearMedia:function(){this.htmlElement.media&&(this.htmlElement.media.src="about:blank",this.htmlElement.media.load())},_html_load:function(){this.status.waitForLoad&&(this.status.waitForLoad=!1,this.htmlElement.media.load()),clearTimeout(this.internal.htmlDlyCmdId)},_html_play:function(a){var b=this,c=this.htmlElement.media;if(this.androidFix.pause=!1,this._html_load(),this.androidFix.setMedia)this.androidFix.play=!0,this.androidFix.time=a;else if(isNaN(a))c.play();else{this.internal.cmdsIgnored&&c.play();try{if(c.seekable&&!("object"==typeof c.seekable&&c.seekable.length>0))throw 1;c.currentTime=a,c.play()}catch(d){return void(this.internal.htmlDlyCmdId=setTimeout(function(){b.play(a)},250))}}this._html_checkWaitForPlay()},_html_pause:function(a){var b=this,c=this.htmlElement.media;if(this.androidFix.play=!1,a>0?this._html_load():clearTimeout(this.internal.htmlDlyCmdId),c.pause(),this.androidFix.setMedia)this.androidFix.pause=!0,this.androidFix.time=a;else if(!isNaN(a))try{if(c.seekable&&!("object"==typeof c.seekable&&c.seekable.length>0))throw 1;c.currentTime=a}catch(d){return void(this.internal.htmlDlyCmdId=setTimeout(function(){b.pause(a)},250))}a>0&&this._html_checkWaitForPlay()},_html_playHead:function(a){var b=this,c=this.htmlElement.media;this._html_load();try{if("object"==typeof c.seekable&&c.seekable.length>0)c.currentTime=a*c.seekable.end(c.seekable.length-1)/100;else{if(!(c.duration>0)||isNaN(c.duration))throw"e";c.currentTime=a*c.duration/100}}catch(d){return void(this.internal.htmlDlyCmdId=setTimeout(function(){b.playHead(a)},250))}this.status.waitForLoad||this._html_checkWaitForPlay()},_html_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.video.jq.css({width:this.status.width,height:this.status.height})))},_html_setProperty:function(a,b){this.html.audio.available&&(this.htmlElement.audio[a]=b),this.html.video.available&&(this.htmlElement.video[a]=b)},_aurora_setAudio:function(b){var c=this;a.each(this.formats,function(a,d){return c.aurora.support[d]&&b[d]?(c.status.src=b[d],c.status.format[d]=!0,c.status.formatType=d,!1):void 0}),this.aurora.player=new AV.Player.fromURL(this.status.src),this._addAuroraEventListeners(this.aurora.player,this.aurora),"auto"===this.options.preload&&(this._aurora_load(),this.status.waitForLoad=!1)},_aurora_resetMedia:function(){this.aurora.player&&this.aurora.player.stop()},_aurora_clearMedia:function(){},_aurora_load:function(){this.status.waitForLoad&&(this.status.waitForLoad=!1,this.aurora.player.preload())},_aurora_play:function(b){this.status.waitForLoad||isNaN(b)||this.aurora.player.seek(b),this.aurora.player.playing||this.aurora.player.play(),this.status.waitForLoad=!1,this._aurora_checkWaitForPlay(),this._updateButtons(!0),this._trigger(a.jPlayer.event.play)},_aurora_pause:function(b){isNaN(b)||this.aurora.player.seek(1e3*b),this.aurora.player.pause(),b>0&&this._aurora_checkWaitForPlay(),this._updateButtons(!1),this._trigger(a.jPlayer.event.pause)},_aurora_playHead:function(a){this.aurora.player.duration>0&&this.aurora.player.seek(a*this.aurora.player.duration/100),this.status.waitForLoad||this._aurora_checkWaitForPlay()},_aurora_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1)},_aurora_volume:function(a){this.aurora.player.volume=100*a},_aurora_mute:function(a){a?(this.aurora.properties.lastvolume=this.aurora.player.volume,this.aurora.player.volume=0):this.aurora.player.volume=this.aurora.properties.lastvolume,this.aurora.properties.muted=a},_flash_setAudio:function(b){var c=this;try{a.each(this.formats,function(a,d){if(c.flash.support[d]&&b[d]){switch(d){case"m4a":case"fla":c._getMovie().fl_setAudio_m4a(b[d]);break;case"mp3":c._getMovie().fl_setAudio_mp3(b[d]);break;case"rtmpa":c._getMovie().fl_setAudio_rtmp(b[d])}return c.status.src=b[d],c.status.format[d]=!0,c.status.formatType=d,!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_setVideo:function(b){var c=this;try{a.each(this.formats,function(a,d){if(c.flash.support[d]&&b[d]){switch(d){case"m4v":case"flv":c._getMovie().fl_setVideo_m4v(b[d]);break;case"rtmpv":c._getMovie().fl_setVideo_rtmp(b[d])}return c.status.src=b[d],c.status.format[d]=!0,c.status.formatType=d,!1}}),"auto"===this.options.preload&&(this._flash_load(),this.status.waitForLoad=!1)}catch(d){this._flashError(d)}},_flash_resetMedia:function(){this.internal.flash.jq.css({width:"0px",height:"0px"}),this._flash_pause(0/0)},_flash_clearMedia:function(){try{this._getMovie().fl_clearMedia()}catch(a){this._flashError(a)}},_flash_load:function(){try{this._getMovie().fl_load()}catch(a){this._flashError(a)}this.status.waitForLoad=!1},_flash_play:function(a){try{this._getMovie().fl_play(a)}catch(b){this._flashError(b)}this.status.waitForLoad=!1,this._flash_checkWaitForPlay()},_flash_pause:function(a){try{this._getMovie().fl_pause(a)}catch(b){this._flashError(b)}a>0&&(this.status.waitForLoad=!1,this._flash_checkWaitForPlay())},_flash_playHead:function(a){try{this._getMovie().fl_play_head(a)}catch(b){this._flashError(b)}this.status.waitForLoad||this._flash_checkWaitForPlay()},_flash_checkWaitForPlay:function(){this.status.waitForPlay&&(this.status.waitForPlay=!1,this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide(),this.status.video&&(this.internal.poster.jq.hide(),this.internal.flash.jq.css({width:this.status.width,height:this.status.height})))},_flash_volume:function(a){try{this._getMovie().fl_volume(a)}catch(b){this._flashError(b)}},_flash_mute:function(a){try{this._getMovie().fl_mute(a)}catch(b){this._flashError(b)}},_getMovie:function(){return document[this.internal.flash.id]},_getFlashPluginVersion:function(){var a,b=0;if(window.ActiveXObject)try{if(a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash")){var c=a.GetVariable("$version");c&&(c=c.split(" ")[1].split(","),b=parseInt(c[0],10)+"."+parseInt(c[1],10))}}catch(d){}else navigator.plugins&&navigator.mimeTypes.length>0&&(a=navigator.plugins["Shockwave Flash"],a&&(b=navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/,"$1")));return 1*b},_checkForFlash:function(a){var b=!1;return this._getFlashPluginVersion()>=a&&(b=!0),b},_validString:function(a){return a&&"string"==typeof a},_limitValue:function(a,b,c){return b>a?b:a>c?c:a},_urlNotSetError:function(b){this._error({type:a.jPlayer.error.URL_NOT_SET,context:b,message:a.jPlayer.errorMsg.URL_NOT_SET,hint:a.jPlayer.errorHint.URL_NOT_SET})},_flashError:function(b){var c;c=this.internal.ready?"FLASH_DISABLED":"FLASH",this._error({type:a.jPlayer.error[c],context:this.internal.flash.swf,message:a.jPlayer.errorMsg[c]+b.message,hint:a.jPlayer.errorHint[c]}),this.internal.flash.jq.css({width:"1px",height:"1px"})},_error:function(b){this._trigger(a.jPlayer.event.error,b),this.options.errorAlerts&&this._alert("Error!"+(b.message?"\n"+b.message:"")+(b.hint?"\n"+b.hint:"")+"\nContext: "+b.context)},_warning:function(c){this._trigger(a.jPlayer.event.warning,b,c),this.options.warningAlerts&&this._alert("Warning!"+(c.message?"\n"+c.message:"")+(c.hint?"\n"+c.hint:"")+"\nContext: "+c.context)},_alert:function(a){var b="jPlayer "+this.version.script+" : id='"+this.internal.self.id+"' : "+a;this.options.consoleAlerts?window.console&&window.console.log&&window.console.log(b):alert(b)},_emulateHtmlBridge:function(){var b=this;a.each(a.jPlayer.emulateMethods.split(/\s+/g),function(a,c){b.internal.domNode[c]=function(a){b[c](a)}}),a.each(a.jPlayer.event,function(c,d){var e=!0;a.each(a.jPlayer.reservedEvent.split(/\s+/g),function(a,b){return b===c?(e=!1,!1):void 0}),e&&b.element.bind(d+".jPlayer.jPlayerHtml",function(){b._emulateHtmlUpdate();var a=document.createEvent("Event");a.initEvent(c,!1,!0),b.internal.domNode.dispatchEvent(a)})})},_emulateHtmlUpdate:function(){var b=this;a.each(a.jPlayer.emulateStatus.split(/\s+/g),function(a,c){b.internal.domNode[c]=b.status[c]}),a.each(a.jPlayer.emulateOptions.split(/\s+/g),function(a,c){b.internal.domNode[c]=b.options[c]})},_destroyHtmlBridge:function(){var b=this;this.element.unbind(".jPlayerHtml");var c=a.jPlayer.emulateMethods+" "+a.jPlayer.emulateStatus+" "+a.jPlayer.emulateOptions;a.each(c.split(/\s+/g),function(a,c){delete b.internal.domNode[c]})}},a.jPlayer.error={FLASH:"e_flash",FLASH_DISABLED:"e_flash_disabled",NO_SOLUTION:"e_no_solution",NO_SUPPORT:"e_no_support",URL:"e_url",URL_NOT_SET:"e_url_not_set",VERSION:"e_version"},a.jPlayer.errorMsg={FLASH:"jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ",FLASH_DISABLED:"jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ",NO_SOLUTION:"No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.",NO_SUPPORT:"It is not possible to play any media format provided in setMedia() on this browser using your current options.",URL:"Media URL could not be loaded.",URL_NOT_SET:"Attempt to issue media playback commands, while no media url is set.",VERSION:"jPlayer "+a.jPlayer.prototype.version.script+" needs Jplayer.swf version "+a.jPlayer.prototype.version.needFlash+" but found "},a.jPlayer.errorHint={FLASH:"Check your swfPath option and that Jplayer.swf is there.",FLASH_DISABLED:"Check that you have not display:none; the jPlayer entity or any ancestor.",NO_SOLUTION:"Review the jPlayer options: support and supplied.",NO_SUPPORT:"Video or audio formats defined in the supplied option are missing.",URL:"Check media URL is valid.",URL_NOT_SET:"Use setMedia() to set the media URL.",VERSION:"Update jPlayer files."},a.jPlayer.warning={CSS_SELECTOR_COUNT:"e_css_selector_count",CSS_SELECTOR_METHOD:"e_css_selector_method",CSS_SELECTOR_STRING:"e_css_selector_string",OPTION_KEY:"e_option_key"},a.jPlayer.warningMsg={CSS_SELECTOR_COUNT:"The number of css selectors found did not equal one: ",CSS_SELECTOR_METHOD:"The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",CSS_SELECTOR_STRING:"The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",OPTION_KEY:"The option requested in jPlayer('option') is undefined."},a.jPlayer.warningHint={CSS_SELECTOR_COUNT:"Check your css selector and the ancestor.",CSS_SELECTOR_METHOD:"Check your method name.",CSS_SELECTOR_STRING:"Check your css selector is a string.",OPTION_KEY:"Check your option name."}}); \ No newline at end of file diff --git a/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.transform.js b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.transform.js new file mode 100644 index 0000000..4683de8 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jplayercircle/js/jquery.transform.js @@ -0,0 +1,532 @@ +/* + * transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate() + * + * limitations: + * - requires jQuery 1.4.3+ + * - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**. + * - transformOrigin is not accessible + * + * latest version and complete README available on Github: + * https://github.com/louisremi/jquery.transform.js + * + * Copyright 2011 @louis_remi + * Licensed under the MIT license. + * + * This saved you an hour of work? + * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON + * + */ +(function ($) { + + /* + * Feature tests and global variables + */ + var div = document.createElement('div'), + divStyle = div.style, + propertyName = 'transform', + suffix = 'Transform', + testProperties = [ + 'O' + suffix, + 'ms' + suffix, + 'Webkit' + suffix, + 'Moz' + suffix, + // prefix-less property + propertyName + ], + i = testProperties.length, + supportProperty, + supportMatrixFilter, + propertyHook, + propertyGet, + rMatrix = /Matrix([^)]*)/; + +// test different vendor prefixes of this property + while (i--) { + if (testProperties[i] in divStyle) { + $.support[propertyName] = supportProperty = testProperties[i]; + + } + } +// IE678 alternative + if (!supportProperty) { + $.support.matrixFilter = supportMatrixFilter = divStyle.filter === ''; + } +// prevent IE memory leak + div = divStyle = null; + +// px isn't the default unit of this property + $.cssNumber[propertyName] = true; + + /* + * fn.css() hooks + */ + if (supportProperty && supportProperty != propertyName) { + // Modern browsers can use jQuery.cssProps as a basic hook + $.cssProps[propertyName] = supportProperty; + + // Firefox needs a complete hook because it stuffs matrix with 'px' + if (supportProperty == 'Moz' + suffix) { + propertyHook = { + get: function (elem, computed) { + return (computed ? + // remove 'px' from the computed matrix + $.css(elem, supportProperty).split('px').join('') : + elem.style[supportProperty] + ) + }, + set: function (elem, value) { + // remove 'px' from matrices + elem.style[supportProperty] = /matrix[^)p]*\)/.test(value) ? + value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, 'matrix$1$2px,$3px') : + value; + } + } + /* Fix two jQuery bugs still present in 1.5.1 + * - rupper is incompatible with IE9, see http://jqbug.com/8346 + * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402 + */ + } else if (/^1\.[0-5](?:\.|$)/.test($.fn.jquery)) { + propertyHook = { + get: function (elem, computed) { + return (computed ? + $.css(elem, supportProperty.replace(/^ms/, 'Ms')) : + elem.style[supportProperty] + ) + } + } + } + /* TODO: leverage hardware acceleration of 3d transform in Webkit only + else if ( supportProperty == 'Webkit' + suffix && support3dTransform ) { + propertyHook = { + set: function( elem, value ) { + elem.style[supportProperty] = + value.replace(); + } + } + }*/ + + } else if (supportMatrixFilter) { + propertyHook = { + get: function (elem, computed) { + var elemStyle = (computed && elem.currentStyle ? elem.currentStyle : elem.style), + matrix; + + if (elemStyle && rMatrix.test(elemStyle.filter)) { + matrix = RegExp.$1.split(','); + matrix = [ + matrix[0].split('=')[1], + matrix[2].split('=')[1], + matrix[1].split('=')[1], + matrix[3].split('=')[1] + ]; + } else { + matrix = [1, 0, 0, 1]; + } + matrix[4] = elemStyle ? elemStyle.left : 0; + matrix[5] = elemStyle ? elemStyle.top : 0; + return "matrix(" + matrix + ")"; + }, + set: function (elem, value, animate) { + var elemStyle = elem.style, + currentStyle, + Matrix, + filter; + + if (!animate) { + elemStyle.zoom = 1; + } + + value = matrix(value); + + // rotate, scale and skew + if (!animate || animate.M) { + Matrix = [ + "Matrix(" + + "M11=" + value[0], + "M12=" + value[2], + "M21=" + value[1], + "M22=" + value[3], + "SizingMethod='auto expand'" + ].join(); + filter = (currentStyle = elem.currentStyle) && currentStyle.filter || elemStyle.filter || ""; + + elemStyle.filter = rMatrix.test(filter) ? + filter.replace(rMatrix, Matrix) : + filter + " progid:DXImageTransform.Microsoft." + Matrix + ")"; + + // center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie + if ((centerOrigin = $.transform.centerOrigin)) { + elemStyle[centerOrigin == 'margin' ? 'marginLeft' : 'left'] = -(elem.offsetWidth / 2) + (elem.clientWidth / 2) + 'px'; + elemStyle[centerOrigin == 'margin' ? 'marginTop' : 'top'] = -(elem.offsetHeight / 2) + (elem.clientHeight / 2) + 'px'; + } + } + + // translate + if (!animate || animate.T) { + // We assume that the elements are absolute positionned inside a relative positionned wrapper + elemStyle.left = value[4] + 'px'; + elemStyle.top = value[5] + 'px'; + } + } + } + } +// populate jQuery.cssHooks with the appropriate hook if necessary + if (propertyHook) { + $.cssHooks[propertyName] = propertyHook; + } +// we need a unique setter for the animation logic + propertyGet = propertyHook && propertyHook.get || $.css; + + /* + * fn.animate() hooks + */ + $.fx.step.transform = function (fx) { + var elem = fx.elem, + start = fx.start, + end = fx.end, + split, + pos = fx.pos, + transform, + translate, + rotate, + scale, + skew, + T = false, + M = false, + prop; + translate = rotate = scale = skew = ''; + + // fx.end and fx.start need to be converted to their translate/rotate/scale/skew components + // so that we can interpolate them + if (!start || typeof start === "string") { + // the following block can be commented out with jQuery 1.5.1+, see #7912 + if (!start) { + start = propertyGet(elem, supportProperty); + } + + // force layout only once per animation + if (supportMatrixFilter) { + elem.style.zoom = 1; + } + + // if the start computed matrix is in end, we are doing a relative animation + split = end.split(start); + if (split.length == 2) { + // remove the start computed matrix to make animations more accurate + end = split.join(''); + fx.origin = start; + start = 'none'; + } + + // start is either 'none' or a matrix(...) that has to be parsed + fx.start = start = start == 'none' ? + { + translate: [0, 0], + rotate: 0, + scale: [1, 1], + skew: [0, 0] + } : + unmatrix(toArray(start)); + + // fx.end has to be parsed and decomposed + fx.end = end = ~end.indexOf('matrix') ? + // bullet-proof parser + unmatrix(matrix(end)) : + // faster and more precise parser + components(end); + + // get rid of properties that do not change + for (prop in start) { + if (prop == 'rotate' ? + start[prop] == end[prop] : + start[prop][0] == end[prop][0] && start[prop][1] == end[prop][1] + ) { + delete start[prop]; + } + } + } + + /* + * We want a fast interpolation algorithm. + * This implies avoiding function calls and sacrifying DRY principle: + * - avoid $.each(function(){}) + * - round values using bitewise hacks, see http://jsperf.com/math-round-vs-hack/3 + */ + if (start.translate) { + // round translate to the closest pixel + translate = ' translate(' + + ((start.translate[0] + (end.translate[0] - start.translate[0]) * pos + .5) | 0) + 'px,' + + ((start.translate[1] + (end.translate[1] - start.translate[1]) * pos + .5) | 0) + 'px' + + ')'; + T = true; + } + if (start.rotate != undefined) { + rotate = ' rotate(' + (start.rotate + (end.rotate - start.rotate) * pos) + 'rad)'; + M = true; + } + if (start.scale) { + scale = ' scale(' + + (start.scale[0] + (end.scale[0] - start.scale[0]) * pos) + ',' + + (start.scale[1] + (end.scale[1] - start.scale[1]) * pos) + + ')'; + M = true; + } + if (start.skew) { + skew = ' skew(' + + (start.skew[0] + (end.skew[0] - start.skew[0]) * pos) + 'rad,' + + (start.skew[1] + (end.skew[1] - start.skew[1]) * pos) + 'rad' + + ')'; + M = true; + } + + // In case of relative animation, restore the origin computed matrix here. + transform = fx.origin ? + fx.origin + translate + skew + scale + rotate : + translate + rotate + scale + skew; + + propertyHook && propertyHook.set ? + propertyHook.set(elem, transform, {M: M, T: T}) : + elem.style[supportProperty] = transform; + }; + + /* + * Utility functions + */ + +// turns a transform string into its 'matrix(A,B,C,D,X,Y)' form (as an array, though) + function matrix(transform) { + transform = transform.split(')'); + var + trim = $.trim + // last element of the array is an empty string, get rid of it + , i = transform.length - 1 + , split, prop, val + , A = 1 + , B = 0 + , C = 0 + , D = 1 + , A_, B_, C_, D_ + , tmp1, tmp2 + , X = 0 + , Y = 0 + ; + // Loop through the transform properties, parse and multiply them + while (i--) { + split = transform[i].split('('); + prop = trim(split[0]); + val = split[1]; + A_ = B_ = C_ = D_ = 0; + + switch (prop) { + case 'translateX': + X += parseInt(val, 10); + continue; + + case 'translateY': + Y += parseInt(val, 10); + continue; + + case 'translate': + val = val.split(','); + X += parseInt(val[0], 10); + Y += parseInt(val[1] || 0, 10); + continue; + + case 'rotate': + val = toRadian(val); + A_ = Math.cos(val); + B_ = Math.sin(val); + C_ = -Math.sin(val); + D_ = Math.cos(val); + break; + + case 'scaleX': + A_ = val; + D_ = 1; + break; + + case 'scaleY': + A_ = 1; + D_ = val; + break; + + case 'scale': + val = val.split(','); + A_ = val[0]; + D_ = val.length > 1 ? val[1] : val[0]; + break; + + case 'skewX': + A_ = D_ = 1; + C_ = Math.tan(toRadian(val)); + break; + + case 'skewY': + A_ = D_ = 1; + B_ = Math.tan(toRadian(val)); + break; + + case 'skew': + A_ = D_ = 1; + val = val.split(','); + C_ = Math.tan(toRadian(val[0])); + B_ = Math.tan(toRadian(val[1] || 0)); + break; + + case 'matrix': + val = val.split(','); + A_ = +val[0]; + B_ = +val[1]; + C_ = +val[2]; + D_ = +val[3]; + X += parseInt(val[4], 10); + Y += parseInt(val[5], 10); + } + // Matrix product + tmp1 = A * A_ + B * C_; + B = A * B_ + B * D_; + tmp2 = C * A_ + D * C_; + D = C * B_ + D * D_; + A = tmp1; + C = tmp2; + } + return [A, B, C, D, X, Y]; + } + +// turns a matrix into its rotate, scale and skew components +// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp + function unmatrix(matrix) { + var + scaleX + , scaleY + , skew + , A = matrix[0] + , B = matrix[1] + , C = matrix[2] + , D = matrix[3] + ; + + // Make sure matrix is not singular + if (A * D - B * C) { + // step (3) + scaleX = Math.sqrt(A * A + B * B); + A /= scaleX; + B /= scaleX; + // step (4) + skew = A * C + B * D; + C -= A * skew; + D -= B * skew; + // step (5) + scaleY = Math.sqrt(C * C + D * D); + C /= scaleY; + D /= scaleY; + skew /= scaleY; + // step (6) + if (A * D < B * C) { + //scaleY = -scaleY; + //skew = -skew; + A = -A; + B = -B; + skew = -skew; + scaleX = -scaleX; + } + + // matrix is singular and cannot be interpolated + } else { + rotate = scaleX = scaleY = skew = 0; + } + + return { + translate: [+matrix[4], +matrix[5]], + rotate: Math.atan2(B, A), + scale: [scaleX, scaleY], + skew: [skew, 0] + } + } + +// parse tranform components of a transform string not containing 'matrix(...)' + function components(transform) { + // split the != transforms + transform = transform.split(')'); + + var translate = [0, 0], + rotate = 0, + scale = [1, 1], + skew = [0, 0], + i = transform.length - 1, + trim = $.trim, + split, name, value; + + // add components + while (i--) { + split = transform[i].split('('); + name = trim(split[0]); + value = split[1]; + + if (name == 'translateX') { + translate[0] += parseInt(value, 10); + + } else if (name == 'translateY') { + translate[1] += parseInt(value, 10); + + } else if (name == 'translate') { + value = value.split(','); + translate[0] += parseInt(value[0], 10); + translate[1] += parseInt(value[1] || 0, 10); + + } else if (name == 'rotate') { + rotate += toRadian(value); + + } else if (name == 'scaleX') { + scale[0] *= value; + + } else if (name == 'scaleY') { + scale[1] *= value; + + } else if (name == 'scale') { + value = value.split(','); + scale[0] *= value[0]; + scale[1] *= (value.length > 1 ? value[1] : value[0]); + + } else if (name == 'skewX') { + skew[0] += toRadian(value); + + } else if (name == 'skewY') { + skew[1] += toRadian(value); + + } else if (name == 'skew') { + value = value.split(','); + skew[0] += toRadian(value[0]); + skew[1] += toRadian(value[1] || '0'); + } + } + + return { + translate: translate, + rotate: rotate, + scale: scale, + skew: skew + }; + } + +// converts an angle string in any unit to a radian Float + function toRadian(value) { + return ~value.indexOf('deg') ? + parseInt(value, 10) * (Math.PI * 2 / 360) : + ~value.indexOf('grad') ? + parseInt(value, 10) * (Math.PI / 200) : + parseFloat(value); + } + +// Converts 'matrix(A,B,C,D,X,Y)' to [A,B,C,D,X,Y] + function toArray(matrix) { + // Fremove the unit of X and Y for Firefox + matrix = /\(([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix); + return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]]; + } + + $.transform = { + centerOrigin: 'margin' + }; + +})(jQuery); diff --git a/src/main/webapp/resources/vendor/jplayercircle/js/mod.csstransforms.min.js b/src/main/resources/static/staticResources/vendor/jplayercircle/js/mod.csstransforms.min.js similarity index 100% rename from src/main/webapp/resources/vendor/jplayercircle/js/mod.csstransforms.min.js rename to src/main/resources/static/staticResources/vendor/jplayercircle/js/mod.csstransforms.min.js diff --git a/src/main/resources/static/staticResources/vendor/jquery-1.12.4.min.js b/src/main/resources/static/staticResources/vendor/jquery-1.12.4.min.js new file mode 100644 index 0000000..e836475 --- /dev/null +++ b/src/main/resources/static/staticResources/vendor/jquery-1.12.4.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.4 | (c) jQuery Foundation | 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=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",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 e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.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()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[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):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"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"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=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)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(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 oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(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"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!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 fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.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},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.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=fa.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=fa.selectors={cacheLength:50,createPseudo:ha,match:W,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(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===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]||fa.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]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.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(ba,ca).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("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.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.replace(P," ")+" ").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,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(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),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).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 Y.test(a.nodeName)},input:function(a){return X.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:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(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,k=[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(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(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 ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(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 va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(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?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(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 va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.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(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.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(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=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},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(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(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.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.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},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().progress(c.notify).done(c.resolve).fail(c.reject):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=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!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&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(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)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(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 Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" - - - <% - /* including audio */ - %>
- -
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-
<% - /* drawing a map */ - %>
- -
<% - /* external resources link */ - %>
- -
\ No newline at end of file +<%@page session="true" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + diff --git a/src/main/webapp/WEB-INF/views/resource.jsp b/src/main/webapp/WEB-INF/views/resource.jsp index 30f3dec..f08ae77 100644 --- a/src/main/webapp/WEB-INF/views/resource.jsp +++ b/src/main/webapp/WEB-INF/views/resource.jsp @@ -1,195 +1,213 @@ -<%@page session="true"%><%@taglib uri="http://www.springframework.org/tags" prefix="sp"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@page session="true" %> +<%@taglib uri="http://www.springframework.org/tags" prefix="sp" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + -${results.getTitle()} — LodView - <%@include file="inc/header.jsp"%> - -
-
- -
-
-
-

${results.getTitle()}

-

- ${results.getMainIRI()} - target="_blank" > + ${results.getTitle()} — LodView + <%@include file="inc/header.jsp" %> + + +
+
+ +
+
+
+

${results.getTitle()}

+

+ ${results.getMainIRI()} + target="_blank" > <${el.getValue().replaceAll("([#/])([^#/]+)$","$1$2")}> - - : ${el.getNsValue().replaceAll(".+:","")} - - - - - -
- -
-

-
- - - - - -
-
-
-
+ + : ${el.getNsValue().replaceAll(".+:","")} + + + + + +
+ +
+

+
+ + + + + +
+
+
+
- - - <%@include file="inc/widgets.jsp"%> - - - - - - <% - /* direct relations */ - %> -
- <% - /* setting class names for colums */ - %> - - - - <%@include file="func/contents.jsp"%> + + + <%@include file="inc/widgets.jsp" %> + + + + + + <% + /* direct relations */ + %> +
+ <% + /* setting class names for colums */ + %> + + + + <%@include file="func/contents.jsp" %> -
- - -
-

- -

- <% - /* first level of blank nodes */ - %> - - -
- - - - - - <%@include file="func/contents.jsp"%> - -
-
+
+ + +
+

+ +

+ <% + /* first level of blank nodes */ + %> + + +
+ + + + + + <%@include file="func/contents.jsp" %> + +
+
- <% - /* second level of blank nodes */ - %> - - - - - -
- - - - - - <%@include file="func/contents.jsp"%> - -
-
-
-
+ <% + /* second level of blank nodes */ + %> + + + + + +
+ + + + + + <%@include file="func/contents.jsp" %> + +
+
+
+
- <% - /* third level of blank nodes */ - %> - - - - - - - -
- - - - - - <%@include file="func/contents.jsp"%> - -
-
-
-
-
-
+ <% + /* third level of blank nodes */ + %> + + + + + + + +
+ + + + + + <%@include file="func/contents.jsp" %> + +
+
+
+
+
+
-
-
- -
-
-
- - -
-
-

- -

-
-
- -
- - -
-

-   -

-
- + + + +
+
+ + + +
+
+

+ +

+
+
+ + + + +
+

+   +

+
+ - \ No newline at end of file + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 56730b2..0000000 --- a/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - contextConfigLocation - /WEB-INF/spring/root-context.xml - - - org.springframework.web.context.ContextLoaderListener - - - appServlet - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - /WEB-INF/spring/appServlet/servlet-context.xml - - 1 - true - - - appServlet - / - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - - encoding - UTF-8 - - - forceEncoding - true - - - - encodingFilter - /* - - - 404 - /error - - - 500 - /error - - - 406 - /error - - - - - \ No newline at end of file diff --git a/src/main/webapp/resources/css/commons.css b/src/main/webapp/resources/css/commons.css deleted file mode 100644 index ba05b6e..0000000 --- a/src/main/webapp/resources/css/commons.css +++ /dev/null @@ -1,1009 +0,0 @@ -/* ********************************************** */ -/* DO NOT CHANGE THIS FILE USE custom.css INSTEAD */ -/* ********************************************** */ -.sp { - background-image: url(../img/lodview-sprite.png); - background-size: 1000px 600px; -} - -div#logoBanner div#logo { - background-size: 134px 40px; - background-image: url(../img/logo-header-lodview.png); - height: 80px; - background-position: left center; - background-repeat: no-repeat; - cursor: pointer; - width: 150px; -} - -a { - text-decoration: none; -} - -body { - font-family: 'Roboto', sans-serif; - font-weight: 300; - line-height: 20px; - font-size: 14px; - background-color: #212121; -} - -strong { - font-weight: 500; -} - -.value div.fixed, .valuecnt div.fixed, #abstract .c2 { - max-width: 760px; - overflow-x: hidden; -} - -label { - display: inline-block; -} - -label a { - font-weight: 300; - font-size: 14px; -} - -label a span { - font-weight: 500; -} - -div#logoBanner { - height: 80px; - background-color: #fff; - padding: 0 24px; -} - -hgroup { - display: block; - min-height: 210px; - color: #fff; - padding: 0 24px; -} - -hgroup h1 { - font-size: 32px; - padding-top: 120px; - line-height: 32px; - font-weight: 300; - margin-right: 100px; -} - -hgroup h1 span { - display: inline-block; - padding-right: 250px; -} - -#seeOnLodlive a { - display: inline-block; - width: 19px; - height: 27px; -} - -#seeOnLodlive { - background-position: -130px 0; - width: 19px; - height: 27px; - position: absolute; - top: 116px; - right: 24px; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=30)"; - filter: alpha(opacity = 30); - opacity: 0.3; -} - -#seeOnLodlive:hover { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter: alpha(opacity = 100); - opacity: 1; -} - -hgroup h2>a.iri { - display: inline-block; - margin-bottom: 8px; - color: #fff; - margin-right: 8px; -} - -hgroup h2>a.iri:hover { - text-decoration: underline; -} - -hgroup h2>span.istance { - float: none; - display: inline-block; - margin-left: -8px; -} - - -hgroup h2 { - font-size: 16px; - padding: 8px 0 24px 0; - font-weight: 300; -} - -hgroup h2>span a { - color: #fff; - font-weight: 300; - display: inline-block; - margin-left: 8px; - margin-top: 2px; - /*text-transform: uppercase;*/ - letter-spacing: .7; - font-size: 13px; -} - -hgroup h2>span a span { - color: #fff; - font-weight: 500; -} - -hgroup h2>span.istance a span.istanceOf{ - font-size:11px; - text-transform: uppercase; - font-weight: 300; -} - -header div#abstract { - padding: 24px; - color: #fff; -} - -header div#abstract .value a { - text-decoration: underline; - color: #fff; -} - -header div#abstract .value a:hover { - text-decoration: none -} - -header div#abstract label { - padding: 0 24px 0 0; -} - -header div#abstract label a { - color: #fff; -} - -header div#abstract label a span { - color: #fff; -} - -aside { - display: block; - background-color: #eee; - color: #fff; - padding: 24px 24px 16px 24px; -} - -#widgets>div#images>a:hover, #widgets>div#linking>a:hover { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; - filter: alpha(opacity = 90); - opacity: 0.9; -} - -#widgets>div#images>a { - min-width: 136px; - height: 136px; - text-align: left; - display: inline-block; - background-image: url(../img/segnaposto-immagine.png); - background-size: 48px 48px; - background-position: center center; - background-repeat: no-repeat; - margin-right: 8px; - margin-bottom: 8px; -} - -aside { - font-size: 0px -} - -aside div.noImg { - width: 125px; - height: 125px; - display: inline-block; - background-position: 0 -105px; - background-size: 300px 250px; -} - -aside div#linking, aside div#images, aside div#audio , aside div#video{ - display: inline-block; -} - -aside div#resourceMapCnt { - display: inline-block; - margin-right: 8px; -} - -aside div#images a img, aside div#linking a span, aside div#resourceMapCnt map , aside div#audio .audio { - height: 136px; - display: inline-block; - width: auto; -}aside div#video{ - height:144px; -} -aside div#video *{ - height: 136px; - display: inline-block; - margin-right: 8px; -} -aside div#audio .audio{ - height: 136px; - display: inline-block; - width: 136px; - margin-right: 8px; - margin-bottom: 8px; - background-position: -520px -65px; -} - -aside div#linking { - margin-bottom: 8px; -} - -aside div#linking a span { - width: 136px; - background-position: -280px -65px; -} - -aside div#resourceMapCnt map { - width: 272px; - background-position: 0 -65px; -} - -.leaflet-popup-content { - color: #000 -} - -.c1, .c3 { - position: absolute -} -h3 { - text-transform: uppercase; - letter-spacing: .7; - font-weight: 300; - color: #212121; - font-size: 11px; -} - -div#directs { - padding: 24px; - background: #fff; - color: #212121; - line-height: 20px; - font-size: 14px; - overflow-x: hidden; -} - -div#bnodes { - padding: 24px; - background: #eee; - color: #212121; - line-height: 20px; - font-size: 14px; -} - -div#inverses { - padding: 24px; - background: #d4d4d4; - color: #212121; - line-height: 20px; - font-size: 14px; -} - -.lloading { - background-image: url(../img/loading-new@2x.gif); - background-size: 22px 7px; - width: 22px; - height: 7px; - display: inline-block; - margin-right: 8px; -} - -.lloadingb { - background-image: url(../img/loading-new-nero@2x.gif); - background-size: 22px 7px; - width: 22px; - height: 7px; - display: inline-block; - margin-left: 16px; -} - -div#inverses .nextArrow { - display: inline-block; - width: 12px; - height: 14px; - margin-left: 8px; - background-position: -60px 3px; -} - -div#inverses .prevArrow { - display: inline-block; - width: 12px; - height: 14px; - margin-left: 16px; - background-position: -45px 3px; -} - -div#lodCloud { - padding: 24px 24px 16px 24px; - background: #fafafa; - color: #212121; - line-height: 16px; - font-size: 12px; - min-height: 64px; -} - -div#lodCloud map { - background-position: -260px -210px; - display: inline-block; - width: 250px; - height: 250px; -} - -div#lodCloud .connected div#counterBlock.content { - color: #fff; -} - -div.toOneLine { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.value div, .valuecnt div { - min-height: 20px -} - -.value div span.derivedTitle, .valuecnt div span.derivedTitle { - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background-repeat: no-repeat; -} - -.value div span.derivedTitle tt, .valuecnt div span.derivedTitle tt { - margin: 5px 0 0 2px; - background-position: -45px -20px; - width: 11px; - display: inline-block; - height: 10px; -} - -div#directs .value a span.derivedTitle, div#bnodes .value a span.derivedTitle, div#inverses .value a span.derivedTitle { - font-weight: 300; -} - -.value div a:hover span.derivedTitle { - text-decoration: none; -} - -div#directs .value>div:not(.value), div#bnodes .valuecnt>div:not(.value), div#inverses .value>div:not(.value) { - padding-bottom: 12px; - margin-top: 12px; - background-image: url(../img/separatoreCorto.png); - background-repeat: no-repeat; - background-size: 16px 1px; - background-position: bottom left; -} -div#directs .c2.multiInLineBlock,div#directs .c4.multiInLineBlock{ - padding-bottom: 8.5px; - padding-top: 8.5px; -} - -.multiInLine{ - display:inline-block; - margin-right: 20px; - line-height:27px; -} - -div#directs .value>div:not(.value):first-child, div#bnodes .valuecnt>div:not(.value):first-child, div#inverses .value>div:not(.value):first-child, div#inverses .value>div:not(.value):nth-of-type(n+2):not(.toOneLine):not(.toMultiLine), div#bnodes .valuecnt>div:not(.value):nth-of-type(n+2):not(.toOneLine):not(.toMultiLine){ - margin-top: 0; -} - -div#directs .value>div:not(.value):last-child, div#bnodes .valuecnt>div:not(.value):last-child, div#inverses .value>div:not(.value):last-child { - padding: 0; - background: none; -} - -div#directs label, div#bnodes label, div#inverses label { - padding: 0 24px 0 0; -} - -div#directs label a, div#bnodes label a, div#inverses label a { - color: #212121; -} - -div#directs label a span, div#bnodes label a span, div#inverses label a span { - color: #212121; -} - -div#directs .dType, div#bnodes .dType { - font-size: 14px; - font-weight: 300; - color: #9e9e9e; - position: absolute; - right: 24px; - text-align: right; - padding-left: 16px; - background-color: #fff; -} - -div#bnodes .dType { - background-color: #eee; -} - -div#directs span.clang, div#abstract span.clang, div#bnodes span.clang, div#bnodes span.clang { - display: inline-block; - text-transform: uppercase; - letter-spacing: .7; - margin-right: 5px; - cursor: pointer; - margin-bottom: 12px; -} - -div#directs span.clang.sel, div#abstract span.clang.sel, div#bnodes span.clang.sel { - text-decoration: underline; -} - -div#directs .value a, div#directs .valuecnt a, div#bnodes .value a, div#bnodes .valuecnt a, div#inverses .value a, div#inverses .valuecnt a { - font-weight: 300; - font-size: 14px; - color: #212121; -} - -div#directs .value a span, div#bnodes .value a span, div#inverses .value a span { - font-weight: 500; - color: #212121; -} - -div#directs .value a:hover, div#bnodes .value a:hover, div#inverses .value a:hover, div#directs .valuecnt a:hover, div#bnodes .valuecnt a:hover, div#inverses .valuecnt a:hover { - text-decoration: underline; -} - -div#directs .c2, div#directs .c4 { - border-bottom: 1px solid #dbdbdb; - padding-bottom: 12px; - padding-top: 12px; -} - -div#bnodes .c2, div#bnodes .c4 { - border-bottom: 1px solid #d2d2d2; - padding-bottom: 12px; - padding-top: 12px; -} - -div#inverses .c2, div#inverses .c4 { - padding-bottom: 12px; - padding-top: 12px; - border-bottom: 1px solid #b6b6b6; -} - -div#inverses .c2 .toOneLine { - min-height: 40px; -} - -div#inverses .c2.opened { - min-height: 648px; -} - -div#bnodes .c2:last-child, div#directs .c2:last-child, div#inverses .c2:last-child, div#bnodes .c4:last-child, div#directs .c4:last-child, div#inverses .c4:last-child { - border-bottom: 0; - padding-bottom: 0; - padding-top: 12px; -} - -div#directs label:nth-child(1), div#bnodes label:nth-child(1), div#inverses label:nth-child(1) { - padding-top: 0; -} - -div#directs label, div#bnodes label, div#inverses label { - padding-top: 12px; -} - -div#directs .c2:nth-child(2), div#bnodes .c2:nth-child(2), div#inverses .c2:nth-child(2), div#directs .c4:nth-child(2), div#bnodes .c4:nth-child(2), div#inverses .c4:nth-child(2) { - padding-top: 0; -} - -div#lodCloud h3 { - margin-bottom: 24px; -} - -div#lodCloud .lloading { - position: absolute; - right: 22px; - top: 28px; -} - -div#lodCloud .connected { - width: 250px; - display: inline-block; - margin-right: 16px; - vertical-align: top; - margin-bottom: 16px; -} - -div#lodCloud .connected .content { - padding: 24px; - background: #e9e9e9; -} - -div#lodCloud .connected .content :last-child { - margin-bottom: 0; -} - -div#lodCloud .connected h5 { - font-weight: 500; -} - -div#lodCloud .connected .more { - margin-top: 1px; - font-weight: 300; - letter-spacing: .7; - font-size: 11px; - text-transform: uppercase; - padding: 24px; - background: #e9e9e9; -} - -div#lodCloud .connected a.link { - color: #212121; - display: block; - margin-top: 8px; - margin-bottom: 24px; -} - -div#lodCloud .connected a:hover { - text-decoration: underline; -} - -div#lodCloud .connected span.imgCnt { - background-position: 0 -210px; - width: 250px; - display: block; -} - -div#lodCloud .connected img.main { - width: 250px; - height: auto; - background: #ffffff; - -} - -.px1 { - width: 1px; - font-size: 1px; - line-height: 1px; -} - -aside.empty, #bnodes.empty, #directs.empty, #inverses.empty, #abstract.empty { - padding: 0; - min-height: 10px; -} -#lodCloud.empty{ - padding: 0; - min-height: 5px; -} - -#inverses.empty { - padding: 0; - min-height: 20px; -} - -footer { - min-height: 176px; - color: #fff; - padding: 24px; -} - -#download { - float: left; - margin-bottom: 30px; -} - -#download a#linkGit { - margin-top: 160px; - display:block; - font-size: 11px; - text-transform: uppercase; - letter-spacing: .7; - color: #b4b4b4; - text-decoration: none; -} - -#download a:hover { - text-decoration: underline -} - -#endpoint { - position: relative; - top: -7px; - font-size: 12px; - line-height: 24px; -} - -#endpoint { - float: right; - color: #fff; -} - -#endpoint ul li { - min-height: 24px; -} - -#endpoint ul { - list-style: none; -} - -#endpoint a { - color: #fff; - cursor: pointer; -} - -#endpoint a:hover { - text-decoration: underline -} - -div#directs .value>div.lang, div#bnodes .value>div.lang, div#inverses .value>div.lang { - background: none; - padding-bottom: 0; - margin-top: 0 -} - -div#loadPanel { - position: fixed; - width: 100%; - bottom: 0; - left: 0; - line-height: 30px; - height: 30px; - padding-left: 24px; - overflow: hidden; - z-index: 1004; -} - -div#loadPanel.cfix { - padding-left: 100%; - margin-left: -300px -} - -div#loadPanel span.ok { - width: 17px; - height: 14px; - display: inline-block; - margin-left: 6px; -} - -div#loadPanel span.ok img { - display: none -} - -div#loadPanel>p { - font-family: 'Roboto', sans-serif; - font-weight: 300; - line-height: 30px; - font-size: 12px; - color: #fff; -} - -#images .errorImg { - width: 136px; - height: 136px; - margin-right:8px; -} - -.connected .errorImg { - width: 250px; - height: 250px; -} - -#errorPage hgroup h1 { - font-size: 150px; - font-weight: 100; - padding-left: 66px; - padding-top: 80px; -} - -#errorPage.error404 div#owl { - background-image: url(../img/owl404.png); - background-size: 224px 283px; - width: 224px; - height: 283px; - position: absolute; - left: 660px; - top: 105px -} - -#errorPage.error500 div#owl { - background-image: url(../img/owl500.png); - background-size: 224px 283px; - position: absolute; - width: 224px; - height: 283px; - left: 660px; - top: 105px -} - -#errorPage div#abstract { - height: 65px; - padding: 0; -} - -#errorPage div#bnodes { - font-size: 20px; - min-height: 186px; - padding: 0 24px 24px 90px; -} - -#errorPage div#bnodes p { - font-size: 30px; - line-height: 40px; - padding-top: 60px; -} - -footer { - -} - -footer #linkBack { - display:block; - background-size: 134px 25px; - background-image: url(../img/logo-footer-lodview.png); - background-position: 0 0; - height:25px; - width:134px; - background-repeat: no-repeat; -} -footer #linkBack:hover { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; - filter: alpha(opacity = 6); - opacity: 0.6; -} -#navigator { - position: fixed; - right: 0; - top: 50%; - margin-top: -32px; - z-index: 5; - width: 40px; - height: 78px; -} - -#navigator div { - width: 40px; - height: 20px; - cursor: pointer; - margin-bottom: 1px; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter: alpha(opacity = 10); - opacity: 0.1; -} - -#navigator div span { - display: none; -} - -#navigator div.hover:hover { - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter: alpha(opacity = 10); - opacity: 1; - position: static; -} - -#navigator div.hover:hover span { - display: inline-block; - position: fixed; - right: 41px; - background-color: #222; - padding: 0 8px; - height: 20px; - color: #fff; - line-height: 20px; - font-size: 12px; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter: alpha(opacity = 10); - opacity: 1; -} - -#navigator div a { - display: block; - width: 40px; - height: 20px; -} - -#navigator div.down { - background-position: 0 -40px; -} - -#navigator div.up { - background-position: 0 0; -} - -#navigator div.top { - background-position: 0 -20px; -} - -@media screen and (max-width: 768px) { - hgroup h1 span { - padding-right: 150px; - } -} -.iph { - width: 22px; - height: 20px; - position:absolute; - left:-20px; -} -.i { - background-position: -105px -35px; - width: 22px; - height: 20px; - position:absolute; - left:-20px; - z-index: 9; - display:none; - cursor:help; -} -.i span{ - display: inline-block; - background-position: -105px -35px; - width: 11px; - height: 11px; - position:relative; - left:4px; - top:5px; - z-index: 9; -} - -.tooltip { - display:none; - background-color: #212121; - font-family: 'Roboto', sans-serif; - font-weight: 300; - line-height: 15px; - font-size: 12px; - color: #fff; - padding: 10px; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; - position:absolute; - left:8px; - margin-top:22px; - width:250px; - z-index: 9; -} -#license{ - padding:12px 0; - line-height:20px; - font-family: 'Roboto', sans-serif; - font-weight: 300; - font-size: 12px; - float:left; - width:100%; - background:#fff; -} -#license div{ - padding:0 24px; -} -#license div a{ - font-weight: 500; - color:#222222 -} -#license div a:hover{ - text-decoration:underline; -} - -/* ********************************** */ -/* CUSTOM FOOTER, HIDDEN BY DEFAULT */ -/* ********************************** */ -#customFooter { - display: none; -} - -/* useful to add information about the project partners (logo) */ -#customFooter #credits { - height: 86px; - background: #e9e9e9; -} - -#customFooter #credits div { - padding: 24px 0 0 24px; -} - -/* useful to add a custom navigation menu */ -#customFooter menu { - height: 43px; - background: #d4d4d4; -} - -#customFooter menu li { - margin: 0 -8px 0 0; - padding: 0 0 0 24px; - font-family: 'Roboto', sans-serif; - font-weight: 300; - font-size: 12px; - display:inline-block; - line-height:43px; -} - -#customFooter menu li a { - color: #000; -} - -#customFooter menu li a:hover { - text-decoration: underline; -} - -/** image zoomer **/ -#hover{ - position: fixed; - width: 100%; - height: 100%; - top: 0; - left: 0; - background:#fff; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)"; - filter: alpha(opacity = 90); - display:none; - z-index: 1006; -} -div.hover{ - position: fixed; - z-index: 1007; -} -div.closemapzoom { - width:14px; - height:14px; - display:inline-block; - background-position: -120px -35px; - position:fixed; - right:19px; - top:19px; - cursor:pointer; - -} -img.hover{ - position: fixed; - z-index: 1007; - top: 100%; - left: 100%; - display:none; -} -.imgTools { - position: absolute; - overflow: hidden; - z-index:999; - display:none; -} - -.imgTools .zoom { - width: 29px; - height: 29px; - background-position: -430px -65px; - display: block; - cursor: pointer; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; - filter: alpha(opacity = 60); - opacity: 0.6; -} -.imgTools .open:hover,.imgTools .zoom:hover{ - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; - filter: alpha(opacity = 100); - opacity: 1; -} -.imgTools .open { - margin-bottom:5px; - cursor: pointer; - width: 14px; - height: 14px; - background-position: -430px -94px; - display: block; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; - filter: alpha(opacity = 60); - opacity: 0.6; -} diff --git a/src/main/webapp/resources/css/commons_2x.css b/src/main/webapp/resources/css/commons_2x.css deleted file mode 100644 index 1bad799..0000000 --- a/src/main/webapp/resources/css/commons_2x.css +++ /dev/null @@ -1,29 +0,0 @@ -/* **************************************** */ -/* SPECIAL DIRECTIVES FOR PIXEL RATIO > 1 */ -/* **************************************** */ -@media ( -webkit-min-device-pixel-ratio : 2) , ( min-resolution : 192dpi) { - .sp { - background-image: url(../img/lodview-sprite@2x.png); - } - div#logoBanner div#logo { - background-image: url(../img/logo-header-lodview@2x.png); - } - footer #linkBack { - background-image: url(../img/logo-footer-lodview@2x.png); - } - div#directs .value>div:not (.value ), div#bnodes .valuecnt>div:not (.value ), div#inverses .value>div:not (.value ) { - background-image: url("img/separatoreCorto@2x.png"); - } - div#directs .value>div.lang, div#bnodes .value>div.lang, div#inverses .value>div.lang { - background: none - } - #errorPage.error404 div#owl { - background-image: url(../img/owl404@2x.png); - } - #errorPage.error500 div#owl { - background-image: url(../img/owl500@2x.png); - } - #widgets>div#images>a { - background-image: url(../img/segnaposto-immagine@2x.png); - } -} diff --git a/src/main/webapp/resources/css/custom.css b/src/main/webapp/resources/css/custom.css deleted file mode 100644 index 891cd6e..0000000 --- a/src/main/webapp/resources/css/custom.css +++ /dev/null @@ -1,25 +0,0 @@ -/* ***************** */ -/* CUSTOM CSS HERE */ -/* ***************** */ -div#logoBanner div#logo { - background-size: 134px 40px; - background-image: url(../img/logo-header-lodview.png); - height: 80px; - background-position: left center; - background-repeat: no-repeat; - cursor: pointer; - width: 150px; -} - -@media ( -webkit-min-device-pixel-ratio : 2) , ( min-resolution : 192dpi) { - div#logoBanner div#logo { - background-image: url(../img/logo-header-lodview@2x.png); - } -} - -/* ********************************** */ -/* CUSTOM FOOTER, HIDDEN BY DEFAULT */ -/* ********************************** */ -#customFooter { - display: none; -} \ No newline at end of file diff --git a/src/main/webapp/resources/css/reset.css b/src/main/webapp/resources/css/reset.css deleted file mode 100644 index 06a13fc..0000000 --- a/src/main/webapp/resources/css/reset.css +++ /dev/null @@ -1,15 +0,0 @@ -/* html5doctor.com Reset v1.6.1 (http://html5doctor.com/html-5-reset-stylesheet/) - http://cssreset.com */ -html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent} -body{line-height:1} -article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block} -nav ul{list-style:none} -blockquote,q{quotes:none} -blockquote:before,blockquote:after,q:before,q:after{content:none} -a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent} -ins{background-color:#ff9;color:#000;text-decoration:none} -mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold} -del{text-decoration:line-through} -abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help} -table{border-collapse:collapse;border-spacing:0} -hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0} -input,select{vertical-align:middle} \ No newline at end of file diff --git a/src/main/webapp/resources/style.css b/src/main/webapp/resources/style.css deleted file mode 100644 index 346ab55..0000000 --- a/src/main/webapp/resources/style.css +++ /dev/null @@ -1,4 +0,0 @@ -@import url('css/reset.css'); /* first of all, reset! */ -@import url('css/commons.css'); /* do not touch this */ -@import url('css/commons_2x.css'); /* pixel ratio > 1 */ -@import url('css/custom.css'); /* your style */ \ No newline at end of file diff --git a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/circle.player.css b/src/main/webapp/resources/vendor/jplayercircle/circle.skin/circle.player.css deleted file mode 100644 index 2f69642..0000000 --- a/src/main/webapp/resources/vendor/jplayercircle/circle.skin/circle.player.css +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Project: CirclePlayer - * http://www.jplayer.org - * - * Copyright (c) 2011 Happyworm Ltd - * - * Author: Silvia Benvenuti - * Edited by: Mark J Panaghiston - * Date: 6th May 2011 - * Artwork inspired by: http://forrst.com/posts/Untitled-CJz - */ -.cp-jplayer{display:inline-block} -.cp-container { - position: relative; - display:inline-block; - width: 70px; /* 200 - (2 * 48) */ - height: 70px; - background-size: 70px 70px; - padding: 33px; - -webkit-tap-highlight-color:rgba(0,0,0,0); - margin-right: 8px; -} - -.cp-container :focus { - border:none; - outline:0; -} - -.cp-buffer-1, -.cp-buffer-2, -.cp-progress-1, -.cp-progress-2 { - position: absolute; - top: 0; - left: 0; - width: 70px; - height: 70px; - clip:rect(0px,35px,70px,0px); - - -moz-border-radius:35px; - -webkit-border-radius:35px; - border-radius:35px; -} - -.cp-buffer-1, -.cp-buffer-2 { - /*background: url("buffer.png") 0 0 no-repeat; - background-size:70px 70px;*/ -} - - -/* FALLBACK for .progress - * (24 steps starting from 1hr filled progress, Decrease second value by 104px for next step) - * (It needs the container selector to work. Or use div) - */ - -.cp-container .cp-fallback { - background: url("progress_sprite.png") no-repeat; - background-position: 0 70px; - background-size:70px 1680px; -} - -.cp-progress-1, -.cp-progress-2 { - background: url("progress.png") 0 0 no-repeat; - background-size:70px 70px; -} - -.cp-buffer-holder, -.cp-progress-holder, -.cp-circle-control { - position:absolute; - width:70px; - height:70px; -} - -.cp-circle-control { - cursor:pointer; -} - -.cp-buffer-holder, -.cp-progress-holder { - clip:rect(0px,70px,70px,35px); - display:none; -} - - -/* This is needed when progress is greater than 50% or for fallback */ - -.cp-buffer-holder.cp-gt50, -.cp-progress-holder.cp-gt50, -.cp-progress.cp-fallback{ - clip:rect(auto, auto, auto, auto); -} - -.cp-controls { - margin:0; - padding: 15px; -} - -.cp-controls li{ - list-style-type:none; - display: block; - - /*IE Fix*/ - position:absolute; -} - -.cp-controls li a{ - position: relative; - display: block; - width:40px; - height:40px; - text-indent:-9999px; - z-index:1; -} - -.cp-controls .cp-play { - background: url("controls.png") 0 0 no-repeat; - background-size:80px 80px; -} - -.cp-controls .cp-play:hover { - background: url("controls.png") -40px 0 no-repeat; - background-size:80px 80px; -} - -.cp-controls .cp-pause { - background: url("controls.png") 0 -40px no-repeat; - background-size:80px 80px; -} - -.cp-controls .cp-pause:hover { - background: url("controls.png") -40px -40px no-repeat; - background-size:80px 80px; -} - -.cp-jplayer { - width: 0; - height: 0; -} diff --git a/src/main/webapp/resources/vendor/jplayercircle/js/circle.player.js b/src/main/webapp/resources/vendor/jplayercircle/js/circle.player.js deleted file mode 100644 index 02c408d..0000000 --- a/src/main/webapp/resources/vendor/jplayercircle/js/circle.player.js +++ /dev/null @@ -1,243 +0,0 @@ -/* - * CirclePlayer for the jPlayer Plugin (jQuery) - * http://www.jplayer.org - * - * Copyright (c) 2009 - 2011 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html - * - * Version: 1.0.1 (jPlayer 2.0.9) - * Date: 30th May 2011 - * - * Author: Mark J Panaghiston @thepag - * - * CirclePlayer prototype developed by: - * Mark Boas @maboa - * Silvia Benvenuti @aulentina - * Jussi Kalliokoski @quinirill - * - * Inspired by : - * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt - * and - * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause - * - * Standing on the shoulders of : - * John Resig @jresig - * Mark Panaghiston @thepag - * Louis-Rémi Babé @Louis_Remi - */ - - -var CirclePlayer = function(jPlayerSelector, media, options) { - var self = this, - - defaults = { - // solution: "flash, html", // For testing Flash with CSS3 - supplied: "m4a, oga", - // Android 2.3 corrupts media element if preload:"none" is used. - // preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too. - cssSelectorAncestor: "#cp_container_1", - cssSelector: { - play: ".cp-play", - pause: ".cp-pause" - } - }, - - cssSelector = { - bufferHolder: ".cp-buffer-holder", - buffer1: ".cp-buffer-1", - buffer2: ".cp-buffer-2", - progressHolder: ".cp-progress-holder", - progress1: ".cp-progress-1", - progress2: ".cp-progress-2", - circleControl: ".cp-circle-control" - }; - - this.cssClass = { - gt50: "cp-gt50", - fallback: "cp-fallback" - }; - - this.spritePitch = 104; - this.spriteRatio = 0.24; // Number of steps / 100 - - this.player = $(jPlayerSelector); - this.media = $.extend({}, media); - this.options = $.extend(true, {}, defaults, options); // Deep copy - - this.cssTransforms = Modernizr.csstransforms; - this.audio = {}; - this.dragging = false; // Indicates if the progressbar is being 'dragged'. - - this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy. - - this.jq = {}; - $.each(cssSelector, function(entity, cssSel) { - self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel); - }); - - this._initSolution(); - this._initPlayer(); -}; - -CirclePlayer.prototype = { - _createHtml: function() { - }, - _initPlayer: function() { - var self = this; - this.player.jPlayer(this.options); - - this.player.bind($.jPlayer.event.ready + this.eventNamespace, function(event) { - if(event.jPlayer.html.used && event.jPlayer.html.audio.available) { - self.audio = $(this).data("jPlayer").htmlElement.audio; - } - $(this).jPlayer("setMedia", self.media); - self._initCircleControl(); - }); - - this.player.bind($.jPlayer.event.play + this.eventNamespace, function(event) { - $(this).jPlayer("pauseOthers"); - }); - - // This event fired as play time increments - this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function(event) { - if (!self.dragging) { - self._timeupdate(event.jPlayer.status.currentPercentAbsolute); - } - }); - - // This event fired as buffered time increments - this.player.bind($.jPlayer.event.progress + this.eventNamespace, function(event) { - var percent = 0; - if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) { - if(self.audio.duration > 0) { - var bufferTime = 0; - for(var i = 0; i < self.audio.buffered.length; i++) { - bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i); - // console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration); - } - percent = 100 * bufferTime / self.audio.duration; - } // else the Metadata has not been read yet. - // console.log("percent = " + percent); - } else { // Fallback if buffered not supported - // percent = event.jPlayer.status.seekPercent; - percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined. - } - self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill. - // Firefox 4 does not always give the final progress event when buffered = 100% - }); - - this.player.bind($.jPlayer.event.ended + this.eventNamespace, function(event) { - self._resetSolution(); - }); - }, - _initSolution: function() { - if (this.cssTransforms) { - this.jq.progressHolder.show(); - this.jq.bufferHolder.show(); - } - else { - this.jq.progressHolder.addClass(this.cssClass.gt50).show(); - this.jq.progress1.addClass(this.cssClass.fallback); - this.jq.progress2.hide(); - this.jq.bufferHolder.hide(); - } - this._resetSolution(); - }, - _resetSolution: function() { - if (this.cssTransforms) { - this.jq.progressHolder.removeClass(this.cssClass.gt50); - this.jq.progress1.css({'transform': 'rotate(0deg)'}); - this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide(); - } - else { - this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px'); - } - }, - _initCircleControl: function() { - var self = this; - this.jq.circleControl.grab({ - onstart: function(){ - self.dragging = true; - }, onmove: function(event){ - var pc = self._getArcPercent(event.position.x, event.position.y); - self.player.jPlayer("playHead", pc).jPlayer("play"); - self._timeupdate(pc); - }, onfinish: function(event){ - self.dragging = false; - var pc = self._getArcPercent(event.position.x, event.position.y); - self.player.jPlayer("playHead", pc).jPlayer("play"); - } - }); - }, - _timeupdate: function(percent) { - var degs = percent * 3.6+"deg"; - - var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch; - - if (percent <= 50) { - if (this.cssTransforms) { - this.jq.progressHolder.removeClass(this.cssClass.gt50); - this.jq.progress1.css({'transform': 'rotate(' + degs + ')'}); - this.jq.progress2.hide(); - } else { // fall back - this.jq.progress1.css('background-position', '0 '+spriteOffset+'px'); - } - } else if (percent <= 100) { - if (this.cssTransforms) { - this.jq.progressHolder.addClass(this.cssClass.gt50); - this.jq.progress1.css({'transform': 'rotate(180deg)'}); - this.jq.progress2.css({'transform': 'rotate(' + degs + ')'}); - this.jq.progress2.show(); - } else { // fall back - this.jq.progress1.css('background-position', '0 '+spriteOffset+'px'); - } - } - }, - _progress: function(percent) { - var degs = percent * 3.6+"deg"; - - if (this.cssTransforms) { - if (percent <= 50) { - this.jq.bufferHolder.removeClass(this.cssClass.gt50); - this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'}); - this.jq.buffer2.hide(); - } else if (percent <= 100) { - this.jq.bufferHolder.addClass(this.cssClass.gt50); - this.jq.buffer1.css({'transform': 'rotate(180deg)'}); - this.jq.buffer2.show(); - this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'}); - } - } - }, - _getArcPercent: function(pageX, pageY) { - var offset = this.jq.circleControl.offset(), - x = pageX - offset.left - this.jq.circleControl.width()/2, - y = pageY - offset.top - this.jq.circleControl.height()/2, - theta = Math.atan2(y,x); - - if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) { - theta = 2 * Math.PI + theta; - } - - // theta is now value between -0.5PI and 1.5PI - // ready to be normalized and applied - - return (theta + Math.PI / 2) / 2 * Math.PI * 10; - }, - setMedia: function(media) { - this.media = $.extend({}, media); - this.player.jPlayer("setMedia", this.media); - }, - play: function(time) { - this.player.jPlayer("play", time); - }, - pause: function(time) { - this.player.jPlayer("pause", time); - }, - destroy: function() { - this.player.unbind(this.eventNamespace); - this.player.jPlayer("destroy"); - } -}; diff --git a/src/main/webapp/resources/vendor/jplayercircle/js/jquery.grab.js b/src/main/webapp/resources/vendor/jplayercircle/js/jquery.grab.js deleted file mode 100644 index d731899..0000000 --- a/src/main/webapp/resources/vendor/jplayercircle/js/jquery.grab.js +++ /dev/null @@ -1,201 +0,0 @@ -/* -jQuery grab -https://github.com/jussi-kalliokoski/jQuery.grab -Ported from Jin.js::gestures -https://github.com/jussi-kalliokoski/jin.js/ -Created by Jussi Kalliokoski -Licensed under MIT License. - -Includes fix for IE -*/ - - -(function($){ - var extend = $.extend, - mousedown = 'mousedown', - mousemove = 'mousemove', - mouseup = 'mouseup', - touchstart = 'touchstart', - touchmove = 'touchmove', - touchend = 'touchend', - touchcancel = 'touchcancel'; - - function unbind(elem, type, func){ - if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin. - return $(elem).unbind(type, func); - } - var fnc, i; - for (i=0; i'; - - var paramStr = [ - '', - '', - '', - '', - '' - ]; - - htmlObj = document.createElement(objStr); - for(var i=0; i < paramStr.length; i++) { - htmlObj.appendChild(document.createElement(paramStr[i])); - } - } else { - var createParam = function(el, n, v) { - var p = document.createElement("param"); - p.setAttribute("name", n); - p.setAttribute("value", v); - el.appendChild(p); - }; - - htmlObj = document.createElement("object"); - htmlObj.setAttribute("id", this.internal.flash.id); - htmlObj.setAttribute("data", this.internal.flash.swf); - htmlObj.setAttribute("type", "application/x-shockwave-flash"); - htmlObj.setAttribute("width", "1"); // Non-zero - htmlObj.setAttribute("height", "1"); // Non-zero - createParam(htmlObj, "flashvars", flashVars); - createParam(htmlObj, "allowscriptaccess", "always"); - createParam(htmlObj, "bgcolor", this.options.backgroundColor); - createParam(htmlObj, "wmode", this.options.wmode); - } - - this.element.append(htmlObj); - this.internal.flash.jq = $(htmlObj); - } - - // Add the HTML solution if being used. - if(this.html.used) { - - // The HTML Audio handlers - if(this.html.audio.available) { - this._addHtmlEventListeners(this.htmlElement.audio, this.html.audio); - this.element.append(this.htmlElement.audio); - this.internal.audio.jq = $("#" + this.internal.audio.id); - } - - // The HTML Video handlers - if(this.html.video.available) { - this._addHtmlEventListeners(this.htmlElement.video, this.html.video); - this.element.append(this.htmlElement.video); - this.internal.video.jq = $("#" + this.internal.video.id); - this.internal.video.jq.css({'width':'0px', 'height':'0px'}); // Using size 0x0 since a .hide() causes issues in iOS - } - } - - // Create the bridge that emulates the HTML Media element on the jPlayer DIV - if( this.options.emulateHtml ) { - this._emulateHtmlBridge(); - } - - if(this.html.used && !this.flash.used) { // If only HTML, then emulate flash ready() call after 100ms. - window.setTimeout( function() { - self.internal.ready = true; - self.version.flash = "n/a"; - self._trigger($.jPlayer.event.ready); - }, 100); - } - - this._updateInterface(); - this._updateButtons(false); - this._updateVolume(this.options.volume); - this._updateMute(this.options.muted); - if(this.css.jq.videoPlay.length) { - this.css.jq.videoPlay.hide(); - } - $.jPlayer.prototype.count++; // Change static variable via prototype. - }, - destroy: function() { - // MJP: The background change remains. Would need to store the original to restore it correctly. - - // Reset the interface, remove seeking effect and times. - this._resetStatus(); - this._updateInterface(); - this._seeked(); - if(this.css.jq.currentTime.length) { - this.css.jq.currentTime.text(""); - } - if(this.css.jq.duration.length) { - this.css.jq.duration.text(""); - } - - if(this.status.srcSet) { // Or you get a bogus error event - this.pause(); // Pauses the media and clears any delayed commands used in the HTML solution. - } - $.each(this.css.jq, function(fn, jq) { // Remove any bindings from the interface controls. - // Check selector is valid before trying to execute method. - if(jq.length) { - jq.unbind(".jPlayer"); - } - }); - if( this.options.emulateHtml ) { - this._destroyHtmlBridge(); - } - this.element.removeData("jPlayer"); // Remove jPlayer data - this.element.unbind(".jPlayer"); // Remove all event handlers created by the jPlayer constructor - this.element.empty(); // Remove the inserted child elements - - this.instances[this.internal.instance] = undefined; // Clear the instance on the static instance object - }, - enable: function() { // Plan to implement - // options.disabled = false - }, - disable: function () { // Plan to implement - // options.disabled = true - }, - _addHtmlEventListeners: function(mediaElement, entity) { - var self = this; - mediaElement.preload = this.options.preload; - mediaElement.muted = this.options.muted; - mediaElement.volume = this.options.volume; - - // Create the event listeners - // Only want the active entity to affect jPlayer and bubble events. - // Using entity.gate so that object is referenced and gate property always current - - mediaElement.addEventListener("progress", function() { - if(entity.gate && !self.status.waitForLoad) { - self._getHtmlStatus(mediaElement); - self._updateInterface(); - self._trigger($.jPlayer.event.progress); - } - }, false); - mediaElement.addEventListener("timeupdate", function() { - if(entity.gate && !self.status.waitForLoad) { - self._getHtmlStatus(mediaElement); - self._updateInterface(); - self._trigger($.jPlayer.event.timeupdate); - } - }, false); - mediaElement.addEventListener("durationchange", function() { - if(entity.gate && !self.status.waitForLoad) { - self.status.duration = this.duration; - self._getHtmlStatus(mediaElement); - self._updateInterface(); - self._trigger($.jPlayer.event.durationchange); - } - }, false); - mediaElement.addEventListener("play", function() { - if(entity.gate && !self.status.waitForLoad) { - self._updateButtons(true); - self._trigger($.jPlayer.event.play); - } - }, false); - mediaElement.addEventListener("playing", function() { - if(entity.gate && !self.status.waitForLoad) { - self._updateButtons(true); - self._seeked(); - self._trigger($.jPlayer.event.playing); - } - }, false); - mediaElement.addEventListener("pause", function() { - if(entity.gate && !self.status.waitForLoad) { - self._updateButtons(false); - self._trigger($.jPlayer.event.pause); - } - }, false); - mediaElement.addEventListener("waiting", function() { - if(entity.gate && !self.status.waitForLoad) { - self._seeking(); - self._trigger($.jPlayer.event.waiting); - } - }, false); - mediaElement.addEventListener("canplay", function() { - if(entity.gate && !self.status.waitForLoad) { - mediaElement.volume = self._volumeFix(self.options.volume); - self._trigger($.jPlayer.event.canplay); - } - }, false); - mediaElement.addEventListener("seeking", function() { - if(entity.gate && !self.status.waitForLoad) { - self._seeking(); - self._trigger($.jPlayer.event.seeking); - } - }, false); - mediaElement.addEventListener("seeked", function() { - if(entity.gate && !self.status.waitForLoad) { - self._seeked(); - self._trigger($.jPlayer.event.seeked); - } - }, false); - mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture. - if(entity.gate && !self.status.waitForLoad) { - self._seeked(); - self._trigger($.jPlayer.event.suspend); - } - }, false); - mediaElement.addEventListener("ended", function() { - if(entity.gate && !self.status.waitForLoad) { - // Order of the next few commands are important. Change the time and then pause. - // Solves a bug in Firefox, where issuing pause 1st causes the media to play from the start. ie., The pause is ignored. - if(!$.jPlayer.browser.webkit) { // Chrome crashes if you do this in conjunction with a setMedia command in an ended event handler. ie., The playlist demo. - self.htmlElement.media.currentTime = 0; // Safari does not care about this command. ie., It works with or without this line. (Both Safari and Chrome are Webkit.) - } - self.htmlElement.media.pause(); // Pause otherwise a click on the progress bar will play from that point, when it shouldn't, since it stopped playback. - self._updateButtons(false); - self._getHtmlStatus(mediaElement, true); // With override true. Otherwise Chrome leaves progress at full. - self._updateInterface(); - self._trigger($.jPlayer.event.ended); - } - }, false); - mediaElement.addEventListener("error", function() { - if(entity.gate && !self.status.waitForLoad) { - self._updateButtons(false); - self._seeked(); - if(self.status.srcSet) { // Deals with case of clearMedia() causing an error event. - clearTimeout(self.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution. - self.status.waitForLoad = true; // Allows the load operation to try again. - self.status.waitForPlay = true; // Reset since a play was captured. - if(self.status.video) { - self.internal.video.jq.css({'width':'0px', 'height':'0px'}); - } - if(self._validString(self.status.media.poster)) { - self.internal.poster.jq.show(); - } - if(self.css.jq.videoPlay.length) { - self.css.jq.videoPlay.show(); - } - self._error( { - type: $.jPlayer.error.URL, - context: self.status.src, // this.src shows absolute urls. Want context to show the url given. - message: $.jPlayer.errorMsg.URL, - hint: $.jPlayer.errorHint.URL - }); - } - } - }, false); - // Create all the other event listeners that bubble up to a jPlayer event from html, without being used by jPlayer. - $.each($.jPlayer.htmlEvent, function(i, eventType) { - mediaElement.addEventListener(this, function() { - if(entity.gate && !self.status.waitForLoad) { - self._trigger($.jPlayer.event[eventType]); - } - }, false); - }); - }, - _getHtmlStatus: function(media, override) { - var ct = 0, d = 0, cpa = 0, sp = 0, cpr = 0; - - if(media.duration) { // Fixes the duration bug in iOS, where the durationchange event occurs when media.duration is not always correct. - this.status.duration = media.duration; - } - ct = media.currentTime; - cpa = (this.status.duration > 0) ? 100 * ct / this.status.duration : 0; - if((typeof media.seekable === "object") && (media.seekable.length > 0)) { - sp = (this.status.duration > 0) ? 100 * media.seekable.end(media.seekable.length-1) / this.status.duration : 100; - cpr = 100 * media.currentTime / media.seekable.end(media.seekable.length-1); - } else { - sp = 100; - cpr = cpa; - } - - if(override) { - ct = 0; - cpr = 0; - cpa = 0; - } - - this.status.seekPercent = sp; - this.status.currentPercentRelative = cpr; - this.status.currentPercentAbsolute = cpa; - this.status.currentTime = ct; - - this.status.readyState = media.readyState; - this.status.networkState = media.networkState; - this.status.playbackRate = media.playbackRate; - this.status.ended = media.ended; - }, - _resetStatus: function() { - this.status = $.extend({}, this.status, $.jPlayer.prototype.status); // Maintains the status properties that persist through a reset. - }, - _trigger: function(eventType, error, warning) { // eventType always valid as called using $.jPlayer.event.eventType - var event = $.Event(eventType); - event.jPlayer = {}; - event.jPlayer.version = $.extend({}, this.version); - event.jPlayer.options = $.extend(true, {}, this.options); // Deep copy - event.jPlayer.status = $.extend(true, {}, this.status); // Deep copy - event.jPlayer.html = $.extend(true, {}, this.html); // Deep copy - event.jPlayer.flash = $.extend(true, {}, this.flash); // Deep copy - if(error) { - event.jPlayer.error = $.extend({}, error); - } - if(warning) { - event.jPlayer.warning = $.extend({}, warning); - } - this.element.trigger(event); - }, - jPlayerFlashEvent: function(eventType, status) { // Called from Flash - if(eventType === $.jPlayer.event.ready && !this.internal.ready) { - this.internal.ready = true; - this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Once Flash generates the ready event, minimise to zero as it is not affected by wmode anymore. - - this.version.flash = status.version; - if(this.version.needFlash !== this.version.flash) { - this._error( { - type: $.jPlayer.error.VERSION, - context: this.version.flash, - message: $.jPlayer.errorMsg.VERSION + this.version.flash, - hint: $.jPlayer.errorHint.VERSION - }); - } - this._trigger(eventType); - } - if(this.flash.gate) { - switch(eventType) { - case $.jPlayer.event.progress: - this._getFlashStatus(status); - this._updateInterface(); - this._trigger(eventType); - break; - case $.jPlayer.event.timeupdate: - this._getFlashStatus(status); - this._updateInterface(); - this._trigger(eventType); - break; - case $.jPlayer.event.play: - this._seeked(); - this._updateButtons(true); - this._trigger(eventType); - break; - case $.jPlayer.event.pause: - this._updateButtons(false); - this._trigger(eventType); - break; - case $.jPlayer.event.ended: - this._updateButtons(false); - this._trigger(eventType); - break; - case $.jPlayer.event.error: - this.status.waitForLoad = true; // Allows the load operation to try again. - this.status.waitForPlay = true; // Reset since a play was captured. - if(this.status.video) { - this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); - } - if(this._validString(this.status.media.poster)) { - this.internal.poster.jq.show(); - } - if(this.css.jq.videoPlay.length) { - this.css.jq.videoPlay.show(); - } - if(this.status.video) { // Set up for another try. Execute before error event. - this._flash_setVideo(this.status.media); - } else { - this._flash_setAudio(this.status.media); - } - this._error( { - type: $.jPlayer.error.URL, - context:status.src, - message: $.jPlayer.errorMsg.URL, - hint: $.jPlayer.errorHint.URL - }); - break; - case $.jPlayer.event.seeking: - this._seeking(); - this._trigger(eventType); - break; - case $.jPlayer.event.seeked: - this._seeked(); - this._trigger(eventType); - break; - case $.jPlayer.event.ready: - // The ready event is handled outside the switch statement. - // Captured here otherwise 2 ready events would be generated if the ready event handler used setMedia. - break; - default: - this._trigger(eventType); - } - } - return false; - }, - _getFlashStatus: function(status) { - this.status.seekPercent = status.seekPercent; - this.status.currentPercentRelative = status.currentPercentRelative; - this.status.currentPercentAbsolute = status.currentPercentAbsolute; - this.status.currentTime = status.currentTime; - this.status.duration = status.duration; - - // The Flash does not generate this information in this release - this.status.readyState = 4; // status.readyState; - this.status.networkState = 0; // status.networkState; - this.status.playbackRate = 1; // status.playbackRate; - this.status.ended = false; // status.ended; - }, - _updateButtons: function(playing) { - this.status.paused = !playing; - if(this.css.jq.play.length && this.css.jq.pause.length) { - if(playing) { - this.css.jq.play.hide(); - this.css.jq.pause.show(); - } else { - this.css.jq.play.show(); - this.css.jq.pause.hide(); - } - } - }, - _updateInterface: function() { - if(this.css.jq.seekBar.length) { - this.css.jq.seekBar.width(this.status.seekPercent+"%"); - } - if(this.css.jq.playBar.length) { - this.css.jq.playBar.width(this.status.currentPercentRelative+"%"); - } - if(this.css.jq.currentTime.length) { - this.css.jq.currentTime.text($.jPlayer.convertTime(this.status.currentTime)); - } - if(this.css.jq.duration.length) { - this.css.jq.duration.text($.jPlayer.convertTime(this.status.duration)); - } - }, - _seeking: function() { - if(this.css.jq.seekBar.length) { - this.css.jq.seekBar.addClass("jp-seeking-bg"); - } - }, - _seeked: function() { - if(this.css.jq.seekBar.length) { - this.css.jq.seekBar.removeClass("jp-seeking-bg"); - } - }, - setMedia: function(media) { - - /* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats. - * media.poster = String: Video poster URL. - * media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file - * media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file - * media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often. - */ - - var self = this; - - this._seeked(); - clearTimeout(this.internal.htmlDlyCmdId); // Clears any delayed commands used in the HTML solution. - - // Store the current html gates, since we need for clearMedia() conditions. - var audioGate = this.html.audio.gate; - var videoGate = this.html.video.gate; - - var supported = false; - $.each(this.formats, function(formatPriority, format) { - var isVideo = self.format[format].media === 'video'; - $.each(self.solutions, function(solutionPriority, solution) { - if(self[solution].support[format] && self._validString(media[format])) { // Format supported in solution and url given for format. - var isHtml = solution === 'html'; - - if(isVideo) { - if(isHtml) { - self.html.audio.gate = false; - self.html.video.gate = true; - self.flash.gate = false; - } else { - self.html.audio.gate = false; - self.html.video.gate = false; - self.flash.gate = true; - } - } else { - if(isHtml) { - self.html.audio.gate = true; - self.html.video.gate = false; - self.flash.gate = false; - } else { - self.html.audio.gate = false; - self.html.video.gate = false; - self.flash.gate = true; - } - } - - // Clear media of the previous solution if: - // - it was Flash - // - changing from HTML to Flash - // - the HTML solution media type (audio or video) remained the same. - // Note that, we must be careful with clearMedia() on iPhone, otherwise clearing the video when changing to audio corrupts the built in video player. - if(self.flash.active || (self.html.active && self.flash.gate) || (audioGate === self.html.audio.gate && videoGate === self.html.video.gate)) { - self.clearMedia(); - } else if(audioGate !== self.html.audio.gate && videoGate !== self.html.video.gate) { // If switching between html elements - self._html_pause(); - // Hide the video if it was being used. - if(self.status.video) { - self.internal.video.jq.css({'width':'0px', 'height':'0px'}); - } - self._resetStatus(); // Since clearMedia usually does this. Execute after status.video useage. - } - - if(isVideo) { - if(isHtml) { - self._html_setVideo(media); - self.html.active = true; - self.flash.active = false; - } else { - self._flash_setVideo(media); - self.html.active = false; - self.flash.active = true; - } - if(self.css.jq.videoPlay.length) { - self.css.jq.videoPlay.show(); - } - self.status.video = true; - } else { - if(isHtml) { - self._html_setAudio(media); - self.html.active = true; - self.flash.active = false; - } else { - self._flash_setAudio(media); - self.html.active = false; - self.flash.active = true; - } - if(self.css.jq.videoPlay.length) { - self.css.jq.videoPlay.hide(); - } - self.status.video = false; - } - - supported = true; - return false; // Exit $.each - } - }); - if(supported) { - return false; // Exit $.each - } - }); - - if(supported) { - // Set poster after the possible clearMedia() command above. IE had issues since the IMG onload event occurred immediately when cached. ie., The clearMedia() hide the poster. - if(this._validString(media.poster)) { - if(this.htmlElement.poster.src !== media.poster) { // Since some browsers do not generate img onload event. - this.htmlElement.poster.src = media.poster; - } else { - this.internal.poster.jq.show(); - } - } else { - this.internal.poster.jq.hide(); // Hide if not used, since clearMedia() does not always occur above. ie., HTML audio <-> video switching. - } - this.status.srcSet = true; - this.status.media = $.extend({}, media); - this._updateButtons(false); - this._updateInterface(); - } else { // jPlayer cannot support any formats provided in this browser - // Pause here if old media could be playing. Otherwise, playing media being changed to bad media would leave the old media playing. - if(this.status.srcSet && !this.status.waitForPlay) { - this.pause(); - } - // Reset all the control flags - this.html.audio.gate = false; - this.html.video.gate = false; - this.flash.gate = false; - this.html.active = false; - this.flash.active = false; - // Reset status and interface. - this._resetStatus(); - this._updateInterface(); - this._updateButtons(false); - // Hide the any old media - this.internal.poster.jq.hide(); - if(this.html.used && this.require.video) { - this.internal.video.jq.css({'width':'0px', 'height':'0px'}); - } - if(this.flash.used) { - this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); - } - // Send an error event - this._error( { - type: $.jPlayer.error.NO_SUPPORT, - context: "{supplied:'" + this.options.supplied + "'}", - message: $.jPlayer.errorMsg.NO_SUPPORT, - hint: $.jPlayer.errorHint.NO_SUPPORT - }); - } - }, - clearMedia: function() { - this._resetStatus(); - this._updateButtons(false); - - this.internal.poster.jq.hide(); - - clearTimeout(this.internal.htmlDlyCmdId); - - if(this.html.active) { - this._html_clearMedia(); - } else if(this.flash.active) { - this._flash_clearMedia(); - } - }, - load: function() { - if(this.status.srcSet) { - if(this.html.active) { - this._html_load(); - } else if(this.flash.active) { - this._flash_load(); - } - } else { - this._urlNotSetError("load"); - } - }, - play: function(time) { - time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler - if(this.status.srcSet) { - if(this.html.active) { - this._html_play(time); - } else if(this.flash.active) { - this._flash_play(time); - } - } else { - this._urlNotSetError("play"); - } - }, - videoPlay: function(e) { // Handles clicks on the play button over the video poster - this.play(); - }, - pause: function(time) { - time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler - if(this.status.srcSet) { - if(this.html.active) { - this._html_pause(time); - } else if(this.flash.active) { - this._flash_pause(time); - } - } else { - this._urlNotSetError("pause"); - } - }, - pauseOthers: function() { - var self = this; - $.each(this.instances, function(i, element) { - if(self.element !== element) { // Do not this instance. - if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. - element.jPlayer("pause"); - } - } - }); - }, - stop: function() { - if(this.status.srcSet) { - if(this.html.active) { - this._html_pause(0); - } else if(this.flash.active) { - this._flash_pause(0); - } - } else { - this._urlNotSetError("stop"); - } - }, - playHead: function(p) { - p = this._limitValue(p, 0, 100); - if(this.status.srcSet) { - if(this.html.active) { - this._html_playHead(p); - } else if(this.flash.active) { - this._flash_playHead(p); - } - } else { - this._urlNotSetError("playHead"); - } - }, - _muted: function(muted) { - this.options.muted = muted; - if(this.html.used) { - this._html_mute(muted); - } - if(this.flash.used) { - this._flash_mute(muted); - } - this._updateMute(muted); - this._updateVolume(this.options.volume); - this._trigger($.jPlayer.event.volumechange); - }, - mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted). - mute = mute === undefined ? true : !!mute; - this._muted(mute); - }, - unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted). - unmute = unmute === undefined ? true : !!unmute; - this._muted(!unmute); - }, - _updateMute: function(mute) { - if(this.css.jq.mute.length && this.css.jq.unmute.length) { - if(mute) { - this.css.jq.mute.hide(); - this.css.jq.unmute.show(); - } else { - this.css.jq.mute.show(); - this.css.jq.unmute.hide(); - } - } - }, - volume: function(v) { - v = this._limitValue(v, 0, 1); - this.options.volume = v; - - if(this.html.used) { - this._html_volume(v); - } - if(this.flash.used) { - this._flash_volume(v); - } - this._updateVolume(v); - this._trigger($.jPlayer.event.volumechange); - }, - volumeBar: function(e) { // Handles clicks on the volumeBar - if(!this.options.muted && this.css.jq.volumeBar.length) { // Ignore clicks when muted - var offset = this.css.jq.volumeBar.offset(); - var x = e.pageX - offset.left; - var w = this.css.jq.volumeBar.width(); - var v = x/w; - this.volume(v); - } - }, - volumeBarValue: function(e) { // Handles clicks on the volumeBarValue - this.volumeBar(e); - }, - _updateVolume: function(v) { - v = this.options.muted ? 0 : v; - if(this.css.jq.volumeBarValue.length) { - this.css.jq.volumeBarValue.width((v*100)+"%"); - } - }, - _volumeFix: function(v) { // Need to review if this is still necessary on latest Chrome - var rnd = 0.001 * Math.random(); // Fix for Chrome 4: Fix volume being set multiple times before playing bug. - var fix = (v < 0.5) ? rnd : -rnd; // Fix for Chrome 4: Solves volume change before play bug. (When new vol == old vol Chrome 4 does nothing!) - return (v + fix); // Fix for Chrome 4: Event solves initial volume not being set correctly. - }, - _cssSelectorAncestor: function(ancestor) { - var self = this; - this.options.cssSelectorAncestor = ancestor; - this._removeUiClass(); - this.ancestorJq = ancestor ? $(ancestor) : []; // Would use $() instead of [], but it is only 1.4+ - if(ancestor && this.ancestorJq.length !== 1) { // So empty strings do not generate the warning. - this._warning( { - type: $.jPlayer.warning.CSS_SELECTOR_COUNT, - context: ancestor, - message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.ancestorJq.length + " found for cssSelectorAncestor.", - hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT - }); - } - this._addUiClass(); - $.each(this.options.cssSelector, function(fn, cssSel) { - self._cssSelector(fn, cssSel); - }); - }, - _cssSelector: function(fn, cssSel) { - var self = this; - if(typeof cssSel === 'string') { - if($.jPlayer.prototype.options.cssSelector[fn]) { - if(this.css.jq[fn] && this.css.jq[fn].length) { - this.css.jq[fn].unbind(".jPlayer"); - } - this.options.cssSelector[fn] = cssSel; - this.css.cs[fn] = this.options.cssSelectorAncestor + " " + cssSel; - - if(cssSel) { // Checks for empty string - this.css.jq[fn] = $(this.css.cs[fn]); - } else { - this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set. - } - - if(this.css.jq[fn].length) { - var handler = function(e) { - self[fn](e); - $(this).blur(); - return false; - }; - this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace - } - - if(cssSel && this.css.jq[fn].length !== 1) { // So empty strings do not generate the warning. ie., they just remove the old one. - this._warning( { - type: $.jPlayer.warning.CSS_SELECTOR_COUNT, - context: this.css.cs[fn], - message: $.jPlayer.warningMsg.CSS_SELECTOR_COUNT + this.css.jq[fn].length + " found for " + fn + " method.", - hint: $.jPlayer.warningHint.CSS_SELECTOR_COUNT - }); - } - } else { - this._warning( { - type: $.jPlayer.warning.CSS_SELECTOR_METHOD, - context: fn, - message: $.jPlayer.warningMsg.CSS_SELECTOR_METHOD, - hint: $.jPlayer.warningHint.CSS_SELECTOR_METHOD - }); - } - } else { - this._warning( { - type: $.jPlayer.warning.CSS_SELECTOR_STRING, - context: cssSel, - message: $.jPlayer.warningMsg.CSS_SELECTOR_STRING, - hint: $.jPlayer.warningHint.CSS_SELECTOR_STRING - }); - } - }, - seekBar: function(e) { // Handles clicks on the seekBar - if(this.css.jq.seekBar) { - var offset = this.css.jq.seekBar.offset(); - var x = e.pageX - offset.left; - var w = this.css.jq.seekBar.width(); - var p = 100*x/w; - this.playHead(p); - } - }, - playBar: function(e) { // Handles clicks on the playBar - this.seekBar(e); - }, - currentTime: function(e) { // Handles clicks on the text - // Added to avoid errors using cssSelector system for the text - }, - duration: function(e) { // Handles clicks on the text - // Added to avoid errors using cssSelector system for the text - }, - // Options code adapted from ui.widget.js (1.8.7). Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1. - option: function(key, value) { - var options = key; - - // Enables use: options(). Returns a copy of options object - if ( arguments.length === 0 ) { - return $.extend( true, {}, this.options ); - } - - if(typeof key === "string") { - var keys = key.split("."); - - // Enables use: options("someOption") Returns a copy of the option. Supports dot notation. - if(value === undefined) { - - var opt = $.extend(true, {}, this.options); - for(var i = 0; i < keys.length; i++) { - if(opt[keys[i]] !== undefined) { - opt = opt[keys[i]]; - } else { - this._warning( { - type: $.jPlayer.warning.OPTION_KEY, - context: key, - message: $.jPlayer.warningMsg.OPTION_KEY, - hint: $.jPlayer.warningHint.OPTION_KEY - }); - return undefined; - } - } - return opt; - } - - // Enables use: options("someOptionObject", someObject}). Creates: {someOptionObject:someObject} - // Enables use: options("someOption", someValue). Creates: {someOption:someValue} - // Enables use: options("someOptionObject.someOption", someValue). Creates: {someOptionObject:{someOption:someValue}} - - options = {}; - var opts = options; - - for(var j = 0; j < keys.length; j++) { - if(j < keys.length - 1) { - opts[keys[j]] = {}; - opts = opts[keys[j]]; - } else { - opts[keys[j]] = value; - } - } - } - - // Otherwise enables use: options(optionObject). Uses original object (the key) - - this._setOptions(options); - - return this; - }, - _setOptions: function(options) { - var self = this; - $.each(options, function(key, value) { // This supports the 2 level depth that the options of jPlayer has. Would review if we ever need more depth. - self._setOption(key, value); - }); - - return this; - }, - _setOption: function(key, value) { - var self = this; - - // The ability to set options is limited at this time. - - switch(key) { - case "volume" : - this.volume(value); - break; - case "muted" : - this._muted(value); - break; - case "cssSelectorAncestor" : - this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor. - break; - case "cssSelector" : - $.each(value, function(fn, cssSel) { - self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks. - }); - break; - case "fullScreen" : - if(this.options[key] !== value) { // if changed - this._removeUiClass(); - this.options[key] = value; - this._refreshSize(); - } - break; - case "size" : - if(!this.options.fullScreen && this.options[key].cssClass !== value.cssClass) { - this._removeUiClass(); - } - this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. - this._refreshSize(); - break; - case "sizeFull" : - if(this.options.fullScreen && this.options[key].cssClass !== value.cssClass) { - this._removeUiClass(); - } - this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. - this._refreshSize(); - break; - case "emulateHtml" : - if(this.options[key] !== value) { // To avoid multiple event handlers being created, if true already. - this.options[key] = value; - if(value) { - this._emulateHtmlBridge(); - } else { - this._destroyHtmlBridge(); - } - } - break; - } - - return this; - }, - // End of: (Options code adapted from ui.widget.js) - - _refreshSize: function() { - this._setSize(); // update status and jPlayer element size - this._addUiClass(); // update the ui class - this._updateSize(); // update internal sizes - }, - _setSize: function() { - // Determine the current size from the options - if(this.options.fullScreen) { - this.status.width = this.options.sizeFull.width; - this.status.height = this.options.sizeFull.height; - this.status.cssClass = this.options.sizeFull.cssClass; - } else { - this.status.width = this.options.size.width; - this.status.height = this.options.size.height; - this.status.cssClass = this.options.size.cssClass; - } - - // Set the size of the jPlayer area. - this.element.css({'width': this.status.width, 'height': this.status.height}); - }, - _addUiClass: function() { - if(this.ancestorJq.length) { - this.ancestorJq.addClass(this.status.cssClass); - } - }, - _removeUiClass: function() { - if(this.ancestorJq.length) { - this.ancestorJq.removeClass(this.status.cssClass); - } - }, - _updateSize: function() { - // The poster uses show/hide so can simply resize it. - this.internal.poster.jq.css({'width': this.status.width, 'height': this.status.height}); - - // Video html or flash resized if necessary at this time. - if(!this.status.waitForPlay) { - if(this.html.active && this.status.video) { // Only if video media - this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); - } - else if(this.flash.active) { - this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); - } - } - }, - fullScreen: function() { - this._setOption("fullScreen", true); - }, - restoreScreen: function() { - this._setOption("fullScreen", false); - }, - _html_initMedia: function() { - if(this.status.srcSet && !this.status.waitForPlay) { - this.htmlElement.media.pause(); - } - if(this.options.preload !== 'none') { - this._html_load(); - } - this._trigger($.jPlayer.event.timeupdate); // The flash generates this event for its solution. - }, - _html_setAudio: function(media) { - var self = this; - // Always finds a format due to checks in setMedia() - $.each(this.formats, function(priority, format) { - if(self.html.support[format] && media[format]) { - self.status.src = media[format]; - self.status.format[format] = true; - self.status.formatType = format; - return false; - } - }); - this.htmlElement.media = this.htmlElement.audio; - this._html_initMedia(); - }, - _html_setVideo: function(media) { - var self = this; - // Always finds a format due to checks in setMedia() - $.each(this.formats, function(priority, format) { - if(self.html.support[format] && media[format]) { - self.status.src = media[format]; - self.status.format[format] = true; - self.status.formatType = format; - return false; - } - }); - this.htmlElement.media = this.htmlElement.video; - this._html_initMedia(); - }, - _html_clearMedia: function() { - if(this.htmlElement.media) { - if(this.htmlElement.media.id === this.internal.video.id) { - this.internal.video.jq.css({'width':'0px', 'height':'0px'}); - } - this.htmlElement.media.pause(); - this.htmlElement.media.src = ""; - this.htmlElement.media.load(); // Stops an old, "in progress" download from continuing the download. Triggers the loadstart, error and emptied events, due to the empty src. Also an abort event if a download was in progress. - } - }, - _html_load: function() { - if(this.status.waitForLoad) { - this.status.waitForLoad = false; - this.htmlElement.media.src = this.status.src; - this.htmlElement.media.load(); - } - clearTimeout(this.internal.htmlDlyCmdId); - }, - _html_play: function(time) { - var self = this; - this._html_load(); // Loads if required and clears any delayed commands. - - this.htmlElement.media.play(); // Before currentTime attempt otherwise Firefox 4 Beta never loads. - - if(!isNaN(time)) { - try { - this.htmlElement.media.currentTime = time; - } catch(err) { - this.internal.htmlDlyCmdId = setTimeout(function() { - self.play(time); - }, 100); - return; // Cancel execution and wait for the delayed command. - } - } - this._html_checkWaitForPlay(); - }, - _html_pause: function(time) { - var self = this; - - if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation. - this._html_load(); // Loads if required and clears any delayed commands. - } else { - clearTimeout(this.internal.htmlDlyCmdId); - } - - // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime. - this.htmlElement.media.pause(); - - if(!isNaN(time)) { - try { - this.htmlElement.media.currentTime = time; - } catch(err) { - this.internal.htmlDlyCmdId = setTimeout(function() { - self.pause(time); - }, 100); - return; // Cancel execution and wait for the delayed command. - } - } - if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. - this._html_checkWaitForPlay(); - } - }, - _html_playHead: function(percent) { - var self = this; - this._html_load(); // Loads if required and clears any delayed commands. - try { - if((typeof this.htmlElement.media.seekable === "object") && (this.htmlElement.media.seekable.length > 0)) { - this.htmlElement.media.currentTime = percent * this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1) / 100; - } else if(this.htmlElement.media.duration > 0 && !isNaN(this.htmlElement.media.duration)) { - this.htmlElement.media.currentTime = percent * this.htmlElement.media.duration / 100; - } else { - throw "e"; - } - } catch(err) { - this.internal.htmlDlyCmdId = setTimeout(function() { - self.playHead(percent); - }, 100); - return; // Cancel execution and wait for the delayed command. - } - if(!this.status.waitForLoad) { - this._html_checkWaitForPlay(); - } - }, - _html_checkWaitForPlay: function() { - if(this.status.waitForPlay) { - this.status.waitForPlay = false; - if(this.css.jq.videoPlay.length) { - this.css.jq.videoPlay.hide(); - } - if(this.status.video) { - this.internal.poster.jq.hide(); - this.internal.video.jq.css({'width': this.status.width, 'height': this.status.height}); - } - } - }, - _html_volume: function(v) { - if(this.html.audio.available) { - this.htmlElement.audio.volume = v; - } - if(this.html.video.available) { - this.htmlElement.video.volume = v; - } - }, - _html_mute: function(m) { - if(this.html.audio.available) { - this.htmlElement.audio.muted = m; - } - if(this.html.video.available) { - this.htmlElement.video.muted = m; - } - }, - _flash_setAudio: function(media) { - var self = this; - try { - // Always finds a format due to checks in setMedia() - $.each(this.formats, function(priority, format) { - if(self.flash.support[format] && media[format]) { - switch (format) { - case "m4a" : - case "fla" : - self._getMovie().fl_setAudio_m4a(media[format]); - break; - case "mp3" : - self._getMovie().fl_setAudio_mp3(media[format]); - break; - } - self.status.src = media[format]; - self.status.format[format] = true; - self.status.formatType = format; - return false; - } - }); - - if(this.options.preload === 'auto') { - this._flash_load(); - this.status.waitForLoad = false; - } - } catch(err) { this._flashError(err); } - }, - _flash_setVideo: function(media) { - var self = this; - try { - // Always finds a format due to checks in setMedia() - $.each(this.formats, function(priority, format) { - if(self.flash.support[format] && media[format]) { - switch (format) { - case "m4v" : - case "flv" : - self._getMovie().fl_setVideo_m4v(media[format]); - break; - } - self.status.src = media[format]; - self.status.format[format] = true; - self.status.formatType = format; - return false; - } - }); - - if(this.options.preload === 'auto') { - this._flash_load(); - this.status.waitForLoad = false; - } - } catch(err) { this._flashError(err); } - }, - _flash_clearMedia: function() { - this.internal.flash.jq.css({'width':'0px', 'height':'0px'}); // Must do via CSS as setting attr() to zero causes a jQuery error in IE. - try { - this._getMovie().fl_clearMedia(); - } catch(err) { this._flashError(err); } - }, - _flash_load: function() { - try { - this._getMovie().fl_load(); - } catch(err) { this._flashError(err); } - this.status.waitForLoad = false; - }, - _flash_play: function(time) { - try { - this._getMovie().fl_play(time); - } catch(err) { this._flashError(err); } - this.status.waitForLoad = false; - this._flash_checkWaitForPlay(); - }, - _flash_pause: function(time) { - try { - this._getMovie().fl_pause(time); - } catch(err) { this._flashError(err); } - if(time > 0) { // Avoids a setMedia() followed by stop() or pause(0) hiding the video play button. - this.status.waitForLoad = false; - this._flash_checkWaitForPlay(); - } - }, - _flash_playHead: function(p) { - try { - this._getMovie().fl_play_head(p); - } catch(err) { this._flashError(err); } - if(!this.status.waitForLoad) { - this._flash_checkWaitForPlay(); - } - }, - _flash_checkWaitForPlay: function() { - if(this.status.waitForPlay) { - this.status.waitForPlay = false; - if(this.css.jq.videoPlay.length) { - this.css.jq.videoPlay.hide(); - } - if(this.status.video) { - this.internal.poster.jq.hide(); - this.internal.flash.jq.css({'width': this.status.width, 'height': this.status.height}); - } - } - }, - _flash_volume: function(v) { - try { - this._getMovie().fl_volume(v); - } catch(err) { this._flashError(err); } - }, - _flash_mute: function(m) { - try { - this._getMovie().fl_mute(m); - } catch(err) { this._flashError(err); } - }, - _getMovie: function() { - return document[this.internal.flash.id]; - }, - _checkForFlash: function (version) { - // Function checkForFlash adapted from FlashReplace by Robert Nyman - // http://code.google.com/p/flashreplace/ - var flashIsInstalled = false; - var flash; - if(window.ActiveXObject){ - try{ - flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version)); - flashIsInstalled = true; - } - catch(e){ - // Throws an error if the version isn't available - } - } - else if(navigator.plugins && navigator.mimeTypes.length > 0){ - flash = navigator.plugins["Shockwave Flash"]; - if(flash){ - var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1"); - if(flashVersion >= version){ - flashIsInstalled = true; - } - } - } - return flashIsInstalled; - }, - _validString: function(url) { - return (url && typeof url === "string"); // Empty strings return false - }, - _limitValue: function(value, min, max) { - return (value < min) ? min : ((value > max) ? max : value); - }, - _urlNotSetError: function(context) { - this._error( { - type: $.jPlayer.error.URL_NOT_SET, - context: context, - message: $.jPlayer.errorMsg.URL_NOT_SET, - hint: $.jPlayer.errorHint.URL_NOT_SET - }); - }, - _flashError: function(error) { - this._error( { - type: $.jPlayer.error.FLASH, - context: this.internal.flash.swf, - message: $.jPlayer.errorMsg.FLASH + error.message, - hint: $.jPlayer.errorHint.FLASH - }); - }, - _error: function(error) { - this._trigger($.jPlayer.event.error, error); - if(this.options.errorAlerts) { - this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context); - } - }, - _warning: function(warning) { - this._trigger($.jPlayer.event.warning, undefined, warning); - if(this.options.warningAlerts) { - this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context); - } - }, - _alert: function(message) { - alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message); - }, - _emulateHtmlBridge: function() { - var self = this, - methods = $.jPlayer.emulateMethods; - - // Emulate methods on jPlayer's DOM element. - $.each( $.jPlayer.emulateMethods.split(/\s+/g), function(i, name) { - self.internal.domNode[name] = function(arg) { - self[name](arg); - }; - - }); - - // Bubble jPlayer events to its DOM element. - $.each($.jPlayer.event, function(eventName,eventType) { - var nativeEvent = true; - $.each( $.jPlayer.reservedEvent.split(/\s+/g), function(i, name) { - if(name === eventName) { - nativeEvent = false; - return false; - } - }); - if(nativeEvent) { - self.element.bind(eventType + ".jPlayer.jPlayerHtml", function() { // With .jPlayer & .jPlayerHtml namespaces. - self._emulateHtmlUpdate(); - var domEvent = document.createEvent("Event"); - domEvent.initEvent(eventName, false, true); - self.internal.domNode.dispatchEvent(domEvent); - }); - } - // The error event would require a special case - }); - - // IE9 has a readyState property on all elements. The document should have it, but all (except media) elements inherit it in IE9. This conflicts with Popcorn, which polls the readyState. - }, - _emulateHtmlUpdate: function() { - var self = this; - - $.each( $.jPlayer.emulateStatus.split(/\s+/g), function(i, name) { - self.internal.domNode[name] = self.status[name]; - }); - $.each( $.jPlayer.emulateOptions.split(/\s+/g), function(i, name) { - self.internal.domNode[name] = self.options[name]; - }); - }, - _destroyHtmlBridge: function() { - var self = this; - - // Bridge event handlers are also removed by destroy() through .jPlayer namespace. - this.element.unbind(".jPlayerHtml"); // Remove all event handlers created by the jPlayer bridge. So you can change the emulateHtml option. - - // Remove the methods and properties - var emulated = $.jPlayer.emulateMethods + " " + $.jPlayer.emulateStatus + " " + $.jPlayer.emulateOptions; - $.each( emulated.split(/\s+/g), function(i, name) { - delete self.internal.domNode[name]; - }); - } - }; - - $.jPlayer.error = { - FLASH: "e_flash", - NO_SOLUTION: "e_no_solution", - NO_SUPPORT: "e_no_support", - URL: "e_url", - URL_NOT_SET: "e_url_not_set", - VERSION: "e_version" - }; - - $.jPlayer.errorMsg = { - FLASH: "jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ", // Used in: _flashError() - NO_SOLUTION: "No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.", // Used in: _init() - NO_SUPPORT: "It is not possible to play any media format provided in setMedia() on this browser using your current options.", // Used in: setMedia() - URL: "Media URL could not be loaded.", // Used in: jPlayerFlashEvent() and _addHtmlEventListeners() - URL_NOT_SET: "Attempt to issue media playback commands, while no media url is set.", // Used in: load(), play(), pause(), stop() and playHead() - VERSION: "jPlayer " + $.jPlayer.prototype.version.script + " needs Jplayer.swf version " + $.jPlayer.prototype.version.needFlash + " but found " // Used in: jPlayerReady() - }; - - $.jPlayer.errorHint = { - FLASH: "Check your swfPath option and that Jplayer.swf is there.", - NO_SOLUTION: "Review the jPlayer options: support and supplied.", - NO_SUPPORT: "Video or audio formats defined in the supplied option are missing.", - URL: "Check media URL is valid.", - URL_NOT_SET: "Use setMedia() to set the media URL.", - VERSION: "Update jPlayer files." - }; - - $.jPlayer.warning = { - CSS_SELECTOR_COUNT: "e_css_selector_count", - CSS_SELECTOR_METHOD: "e_css_selector_method", - CSS_SELECTOR_STRING: "e_css_selector_string", - OPTION_KEY: "e_option_key" - }; - - $.jPlayer.warningMsg = { - CSS_SELECTOR_COUNT: "The number of css selectors found did not equal one: ", - CSS_SELECTOR_METHOD: "The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.", - CSS_SELECTOR_STRING: "The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.", - OPTION_KEY: "The option requested in jPlayer('option') is undefined." - }; - - $.jPlayer.warningHint = { - CSS_SELECTOR_COUNT: "Check your css selector and the ancestor.", - CSS_SELECTOR_METHOD: "Check your method name.", - CSS_SELECTOR_STRING: "Check your css selector is a string.", - OPTION_KEY: "Check your option name." - }; -})(jQuery); diff --git a/src/main/webapp/resources/vendor/jplayercircle/js/jquery.transform.js b/src/main/webapp/resources/vendor/jplayercircle/js/jquery.transform.js deleted file mode 100644 index db58781..0000000 --- a/src/main/webapp/resources/vendor/jplayercircle/js/jquery.transform.js +++ /dev/null @@ -1,532 +0,0 @@ -/* - * transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate() - * - * limitations: - * - requires jQuery 1.4.3+ - * - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**. - * - transformOrigin is not accessible - * - * latest version and complete README available on Github: - * https://github.com/louisremi/jquery.transform.js - * - * Copyright 2011 @louis_remi - * Licensed under the MIT license. - * - * This saved you an hour of work? - * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON - * - */ -(function( $ ) { - -/* - * Feature tests and global variables - */ -var div = document.createElement('div'), - divStyle = div.style, - propertyName = 'transform', - suffix = 'Transform', - testProperties = [ - 'O' + suffix, - 'ms' + suffix, - 'Webkit' + suffix, - 'Moz' + suffix, - // prefix-less property - propertyName - ], - i = testProperties.length, - supportProperty, - supportMatrixFilter, - propertyHook, - propertyGet, - rMatrix = /Matrix([^)]*)/; - -// test different vendor prefixes of this property -while ( i-- ) { - if ( testProperties[i] in divStyle ) { - $.support[propertyName] = supportProperty = testProperties[i]; - continue; - } -} -// IE678 alternative -if ( !supportProperty ) { - $.support.matrixFilter = supportMatrixFilter = divStyle.filter === ''; -} -// prevent IE memory leak -div = divStyle = null; - -// px isn't the default unit of this property -$.cssNumber[propertyName] = true; - -/* - * fn.css() hooks - */ -if ( supportProperty && supportProperty != propertyName ) { - // Modern browsers can use jQuery.cssProps as a basic hook - $.cssProps[propertyName] = supportProperty; - - // Firefox needs a complete hook because it stuffs matrix with 'px' - if ( supportProperty == 'Moz' + suffix ) { - propertyHook = { - get: function( elem, computed ) { - return (computed ? - // remove 'px' from the computed matrix - $.css( elem, supportProperty ).split('px').join(''): - elem.style[supportProperty] - ) - }, - set: function( elem, value ) { - // remove 'px' from matrices - elem.style[supportProperty] = /matrix[^)p]*\)/.test(value) ? - value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, 'matrix$1$2px,$3px'): - value; - } - } - /* Fix two jQuery bugs still present in 1.5.1 - * - rupper is incompatible with IE9, see http://jqbug.com/8346 - * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402 - */ - } else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) { - propertyHook = { - get: function( elem, computed ) { - return (computed ? - $.css( elem, supportProperty.replace(/^ms/, 'Ms') ): - elem.style[supportProperty] - ) - } - } - } - /* TODO: leverage hardware acceleration of 3d transform in Webkit only - else if ( supportProperty == 'Webkit' + suffix && support3dTransform ) { - propertyHook = { - set: function( elem, value ) { - elem.style[supportProperty] = - value.replace(); - } - } - }*/ - -} else if ( supportMatrixFilter ) { - propertyHook = { - get: function( elem, computed ) { - var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ), - matrix; - - if ( elemStyle && rMatrix.test( elemStyle.filter ) ) { - matrix = RegExp.$1.split(','); - matrix = [ - matrix[0].split('=')[1], - matrix[2].split('=')[1], - matrix[1].split('=')[1], - matrix[3].split('=')[1] - ]; - } else { - matrix = [1,0,0,1]; - } - matrix[4] = elemStyle ? elemStyle.left : 0; - matrix[5] = elemStyle ? elemStyle.top : 0; - return "matrix(" + matrix + ")"; - }, - set: function( elem, value, animate ) { - var elemStyle = elem.style, - currentStyle, - Matrix, - filter; - - if ( !animate ) { - elemStyle.zoom = 1; - } - - value = matrix(value); - - // rotate, scale and skew - if ( !animate || animate.M ) { - Matrix = [ - "Matrix("+ - "M11="+value[0], - "M12="+value[2], - "M21="+value[1], - "M22="+value[3], - "SizingMethod='auto expand'" - ].join(); - filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || ""; - - elemStyle.filter = rMatrix.test(filter) ? - filter.replace(rMatrix, Matrix) : - filter + " progid:DXImageTransform.Microsoft." + Matrix + ")"; - - // center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie - if ( (centerOrigin = $.transform.centerOrigin) ) { - elemStyle[centerOrigin == 'margin' ? 'marginLeft' : 'left'] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + 'px'; - elemStyle[centerOrigin == 'margin' ? 'marginTop' : 'top'] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + 'px'; - } - } - - // translate - if ( !animate || animate.T ) { - // We assume that the elements are absolute positionned inside a relative positionned wrapper - elemStyle.left = value[4] + 'px'; - elemStyle.top = value[5] + 'px'; - } - } - } -} -// populate jQuery.cssHooks with the appropriate hook if necessary -if ( propertyHook ) { - $.cssHooks[propertyName] = propertyHook; -} -// we need a unique setter for the animation logic -propertyGet = propertyHook && propertyHook.get || $.css; - -/* - * fn.animate() hooks - */ -$.fx.step.transform = function( fx ) { - var elem = fx.elem, - start = fx.start, - end = fx.end, - split, - pos = fx.pos, - transform, - translate, - rotate, - scale, - skew, - T = false, - M = false, - prop; - translate = rotate = scale = skew = ''; - - // fx.end and fx.start need to be converted to their translate/rotate/scale/skew components - // so that we can interpolate them - if ( !start || typeof start === "string" ) { - // the following block can be commented out with jQuery 1.5.1+, see #7912 - if (!start) { - start = propertyGet( elem, supportProperty ); - } - - // force layout only once per animation - if ( supportMatrixFilter ) { - elem.style.zoom = 1; - } - - // if the start computed matrix is in end, we are doing a relative animation - split = end.split(start); - if ( split.length == 2 ) { - // remove the start computed matrix to make animations more accurate - end = split.join(''); - fx.origin = start; - start = 'none'; - } - - // start is either 'none' or a matrix(...) that has to be parsed - fx.start = start = start == 'none'? - { - translate: [0,0], - rotate: 0, - scale: [1,1], - skew: [0,0] - }: - unmatrix( toArray(start) ); - - // fx.end has to be parsed and decomposed - fx.end = end = ~end.indexOf('matrix')? - // bullet-proof parser - unmatrix(matrix(end)): - // faster and more precise parser - components(end); - - // get rid of properties that do not change - for ( prop in start) { - if ( prop == 'rotate' ? - start[prop] == end[prop]: - start[prop][0] == end[prop][0] && start[prop][1] == end[prop][1] - ) { - delete start[prop]; - } - } - } - - /* - * We want a fast interpolation algorithm. - * This implies avoiding function calls and sacrifying DRY principle: - * - avoid $.each(function(){}) - * - round values using bitewise hacks, see http://jsperf.com/math-round-vs-hack/3 - */ - if ( start.translate ) { - // round translate to the closest pixel - translate = ' translate('+ - ((start.translate[0] + (end.translate[0] - start.translate[0]) * pos + .5) | 0) +'px,'+ - ((start.translate[1] + (end.translate[1] - start.translate[1]) * pos + .5) | 0) +'px'+ - ')'; - T = true; - } - if ( start.rotate != undefined ) { - rotate = ' rotate('+ (start.rotate + (end.rotate - start.rotate) * pos) +'rad)'; - M = true; - } - if ( start.scale ) { - scale = ' scale('+ - (start.scale[0] + (end.scale[0] - start.scale[0]) * pos) +','+ - (start.scale[1] + (end.scale[1] - start.scale[1]) * pos) + - ')'; - M = true; - } - if ( start.skew ) { - skew = ' skew('+ - (start.skew[0] + (end.skew[0] - start.skew[0]) * pos) +'rad,'+ - (start.skew[1] + (end.skew[1] - start.skew[1]) * pos) +'rad'+ - ')'; - M = true; - } - - // In case of relative animation, restore the origin computed matrix here. - transform = fx.origin ? - fx.origin + translate + skew + scale + rotate: - translate + rotate + scale + skew; - - propertyHook && propertyHook.set ? - propertyHook.set( elem, transform, {M: M, T: T} ): - elem.style[supportProperty] = transform; -}; - -/* - * Utility functions - */ - -// turns a transform string into its 'matrix(A,B,C,D,X,Y)' form (as an array, though) -function matrix( transform ) { - transform = transform.split(')'); - var - trim = $.trim - // last element of the array is an empty string, get rid of it - , i = transform.length -1 - , split, prop, val - , A = 1 - , B = 0 - , C = 0 - , D = 1 - , A_, B_, C_, D_ - , tmp1, tmp2 - , X = 0 - , Y = 0 - ; - // Loop through the transform properties, parse and multiply them - while (i--) { - split = transform[i].split('('); - prop = trim(split[0]); - val = split[1]; - A_ = B_ = C_ = D_ = 0; - - switch (prop) { - case 'translateX': - X += parseInt(val, 10); - continue; - - case 'translateY': - Y += parseInt(val, 10); - continue; - - case 'translate': - val = val.split(','); - X += parseInt(val[0], 10); - Y += parseInt(val[1] || 0, 10); - continue; - - case 'rotate': - val = toRadian(val); - A_ = Math.cos(val); - B_ = Math.sin(val); - C_ = -Math.sin(val); - D_ = Math.cos(val); - break; - - case 'scaleX': - A_ = val; - D_ = 1; - break; - - case 'scaleY': - A_ = 1; - D_ = val; - break; - - case 'scale': - val = val.split(','); - A_ = val[0]; - D_ = val.length>1 ? val[1] : val[0]; - break; - - case 'skewX': - A_ = D_ = 1; - C_ = Math.tan(toRadian(val)); - break; - - case 'skewY': - A_ = D_ = 1; - B_ = Math.tan(toRadian(val)); - break; - - case 'skew': - A_ = D_ = 1; - val = val.split(','); - C_ = Math.tan(toRadian(val[0])); - B_ = Math.tan(toRadian(val[1] || 0)); - break; - - case 'matrix': - val = val.split(','); - A_ = +val[0]; - B_ = +val[1]; - C_ = +val[2]; - D_ = +val[3]; - X += parseInt(val[4], 10); - Y += parseInt(val[5], 10); - } - // Matrix product - tmp1 = A * A_ + B * C_; - B = A * B_ + B * D_; - tmp2 = C * A_ + D * C_; - D = C * B_ + D * D_; - A = tmp1; - C = tmp2; - } - return [A,B,C,D,X,Y]; -} - -// turns a matrix into its rotate, scale and skew components -// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp -function unmatrix(matrix) { - var - scaleX - , scaleY - , skew - , A = matrix[0] - , B = matrix[1] - , C = matrix[2] - , D = matrix[3] - ; - - // Make sure matrix is not singular - if ( A * D - B * C ) { - // step (3) - scaleX = Math.sqrt( A * A + B * B ); - A /= scaleX; - B /= scaleX; - // step (4) - skew = A * C + B * D; - C -= A * skew; - D -= B * skew; - // step (5) - scaleY = Math.sqrt( C * C + D * D ); - C /= scaleY; - D /= scaleY; - skew /= scaleY; - // step (6) - if ( A * D < B * C ) { - //scaleY = -scaleY; - //skew = -skew; - A = -A; - B = -B; - skew = -skew; - scaleX = -scaleX; - } - - // matrix is singular and cannot be interpolated - } else { - rotate = scaleX = scaleY = skew = 0; - } - - return { - translate: [+matrix[4], +matrix[5]], - rotate: Math.atan2(B, A), - scale: [scaleX, scaleY], - skew: [skew, 0] - } -} - -// parse tranform components of a transform string not containing 'matrix(...)' -function components( transform ) { - // split the != transforms - transform = transform.split(')'); - - var translate = [0,0], - rotate = 0, - scale = [1,1], - skew = [0,0], - i = transform.length -1, - trim = $.trim, - split, name, value; - - // add components - while ( i-- ) { - split = transform[i].split('('); - name = trim(split[0]); - value = split[1]; - - if (name == 'translateX') { - translate[0] += parseInt(value, 10); - - } else if (name == 'translateY') { - translate[1] += parseInt(value, 10); - - } else if (name == 'translate') { - value = value.split(','); - translate[0] += parseInt(value[0], 10); - translate[1] += parseInt(value[1] || 0, 10); - - } else if (name == 'rotate') { - rotate += toRadian(value); - - } else if (name == 'scaleX') { - scale[0] *= value; - - } else if (name == 'scaleY') { - scale[1] *= value; - - } else if (name == 'scale') { - value = value.split(','); - scale[0] *= value[0]; - scale[1] *= (value.length>1? value[1] : value[0]); - - } else if (name == 'skewX') { - skew[0] += toRadian(value); - - } else if (name == 'skewY') { - skew[1] += toRadian(value); - - } else if (name == 'skew') { - value = value.split(','); - skew[0] += toRadian(value[0]); - skew[1] += toRadian(value[1] || '0'); - } - } - - return { - translate: translate, - rotate: rotate, - scale: scale, - skew: skew - }; -} - -// converts an angle string in any unit to a radian Float -function toRadian(value) { - return ~value.indexOf('deg') ? - parseInt(value,10) * (Math.PI * 2 / 360): - ~value.indexOf('grad') ? - parseInt(value,10) * (Math.PI/200): - parseFloat(value); -} - -// Converts 'matrix(A,B,C,D,X,Y)' to [A,B,C,D,X,Y] -function toArray(matrix) { - // Fremove the unit of X and Y for Firefox - matrix = /\(([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix); - return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]]; -} - -$.transform = { - centerOrigin: 'margin' -}; - -})( jQuery ); \ No newline at end of file diff --git a/src/main/webapp/resources/vendor/jquery.min.js b/src/main/webapp/resources/vendor/jquery.min.js deleted file mode 100644 index d3a4400..0000000 --- a/src/main/webapp/resources/vendor/jquery.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.2 | (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="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,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=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.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},m.extend=m.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||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},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=r(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(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","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}"+L+"?|("+L+")|.)","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)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(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||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(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 H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==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+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(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 pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&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="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(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 p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),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))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),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===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(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?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.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 gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.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},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.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=gb.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=gb.selectors={cacheLength:50,createPseudo:ib,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]||gb.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]&&gb.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("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.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.replace(Q," ")+" ").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()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(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),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.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:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(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 tb(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 ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(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 wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(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?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(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 wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(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]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.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)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(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&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.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?m.extend(a,d):d}},e={};return d.pipe=d.then,m.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&&m.isFunction(a.promise)?e:0,g=1===f?a:m.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]&&m.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;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; -return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.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.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.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 m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:k.htmlSerialize?[0,"",""]:[1,"X
","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(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=wb(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?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(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,m.cleanData(ub(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,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("