diff --git a/.gitignore b/.gitignore index 15bdd96..f33ace2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ -/target -/.idea +Thumbs.db +.DS_Store +.gradle +build/ +out/ +.idea *.iml +*.ipr +*.iws +.project +.settings +.classpath diff --git a/.travis.yml b/.travis.yml index bec923b..4e45ac2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,23 @@ +dist: trusty language: groovy jdk: -- oraclejdk7 +- oraclejdk8 sudo: false branches: only: - master -before_install: - - wget -q https://raw.githubusercontent.com/AtlasOfLivingAustralia/travis-build-configuration/master/ala_common.sh - - chmod +x ala_common.sh - - source ./ala_common.sh - - ala_travis_grails_setup_env -script: - - ala_travis_grails_build + - develop +before_cache: +- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock +- rm -fr $HOME/.gradle/caches/*/plugin-resolution/ +cache: + directories: + - "$HOME/.m2" + - "$HOME/.gradle/caches/" + - "$HOME/.gradle/wrapper/" +after_success: +- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && travis_retry ./gradlew publish' env: global: - - secure: XXXTssBnWIBinafmyop1zf/2Pf81hpr0IisjfUd9lw4InfnbICNChS6P/ovfdtFu062xeVYbAgUQLCec1KlPDZQ32UgxFGU74EQ/1M70bJULsxd35UBpTNkhUyNQIcr9DkOhMYahvQbmySv5JGVFiT9ry/38xzQsHfYCQPs5dJY= - - secure: FHlKa+UKFJdz/4AlfIo6rspYR6+KGOND4hk13LJN3QZCHRjM2ij9toqDxP74aH4VGpaUzEaKy1cC8hqE2F97VbptrFo2NtDEl9fJ6Z/+3lPo3tr6PZ69WZqex//bO+kkpjEn0KspLc92cCfaVOJxHWu5QcQ+C1SddfTwY5FuHPU= + - secure: Z6Jfqbjh+XtuJZpVEmBq3ZarQYG2Hb++md9uBKQeWyy23pM7Mh3S3enne3DNs7zyPEUYVr+udUZI5uGyKmjMKZqAgacZZeAtaj4tcJyZPJDzxCTyxzA+BlcYT3/tdmv/9jH4iwolp9CPHGZA69WhlttV9NLg9GBCpElfxi2bs7A= + - secure: Bl6/Y0aI9Dq3CxZBJgES+M39O62+zkxzI93/6R0g0b7e86i6v5l319Y9fi3PLQ+YsIwJDMMSPvksKOLCk+e0WrizcdF21fDcJlHyO6WrnPoZIHA+dvMJ2AORIbHtBWo5KdczDmWR9/n2UkV6xwRZ0MRZ25bZLy3AsHh/I/5FMPA= diff --git a/README.md b/README.md index c266d49..4b37f06 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -### specimenbrowser [![Build Status](https://travis-ci.org/AtlasOfLivingAustralia/specimenbrowser.svg?branch=master)](https://travis-ci.org/AtlasOfLivingAustralia/specimenbrowser) +### specimenbrowser [![Build Status](https://travis-ci.com/AtlasOfLivingAustralia/specimenbrowser.svg?branch=master)](https://travis-ci.com/AtlasOfLivingAustralia/specimenbrowser) Browsing application for specimen images in Australian collections. This application make use of biocache, collectory and image services. diff --git a/application.properties b/application.properties deleted file mode 100644 index feddc65..0000000 --- a/application.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Grails Metadata file -#Wed Feb 04 20:00:21 EST 2015 -app.grails.version=2.3.11 -app.name=specimenbrowser -app.servlet.version=2.5 -app.version=1.3-SNAPSHOT diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e1c932b --- /dev/null +++ b/build.gradle @@ -0,0 +1,156 @@ +buildscript { + repositories { + mavenLocal() + maven { url "https://nexus.ala.org.au/content/groups/public/" } + maven { url "https://repo.grails.org/grails/core" } + } + dependencies { + classpath "org.grails:grails-gradle-plugin:$grailsVersion" + classpath "gradle.plugin.com.github.erdi.webdriver-binaries:webdriver-binaries-gradle-plugin:2.0" + // classpath "org.grails.plugins:hibernate5:7.0.4" + classpath "com.bertramlabs.plugins:asset-pipeline-gradle:3.2.4" + } +} + +version "2.0" +group "au.org.ala" + +apply plugin:"eclipse" +apply plugin:"idea" +apply plugin:"war" +apply plugin:"org.grails.grails-web" +apply plugin:"com.github.erdi.webdriver-binaries" +apply plugin:"com.bertramlabs.asset-pipeline" +apply plugin:"org.grails.grails-gsp" +apply plugin:"maven-publish" + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +repositories { + mavenLocal() + maven { url "http://nexus.ala.org.au/content/groups/public/" } + maven { url "https://repo.grails.org/grails/core" } +} + +configurations { + developmentOnly + runtimeClasspath { + extendsFrom developmentOnly + } +} + +dependencies { + developmentOnly("org.springframework.boot:spring-boot-devtools") + compile "org.springframework.boot:spring-boot-starter-logging" + compile "org.springframework.boot:spring-boot-autoconfigure" + compile "org.grails:grails-core" + compile "org.springframework.boot:spring-boot-starter-actuator" + compile "org.springframework.boot:spring-boot-starter-tomcat" + compile "org.grails:grails-web-boot" + compile "org.grails:grails-logging" + compile "org.grails:grails-plugin-rest" + compile "org.grails:grails-plugin-i18n" + compile "org.grails:grails-plugin-services" + compile "org.grails:grails-plugin-url-mappings" + compile "org.grails:grails-plugin-interceptors" + compile "org.grails.plugins:cache" + compile "org.grails.plugins:async" + compile "org.grails.plugins:events" + compile "org.grails.plugins:gsp" + compileOnly "io.micronaut:micronaut-inject-groovy" + console "org.grails:grails-console" + profile "org.grails.profiles:web" + runtime "org.glassfish.web:el-impl:2.1.2-b03" + runtime "javax.xml.bind:jaxb-api:2.3.1" + runtime "xml-apis:xml-apis:1.4.01" + runtime "com.bertramlabs.plugins:asset-pipeline-grails:3.2.4" + testCompile "io.micronaut:micronaut-inject-groovy" + testCompile "org.mockito:mockito-core" + testCompile "org.grails:grails-web-testing-support" + testCompile "org.grails.plugins:geb" + testCompile "org.seleniumhq.selenium:selenium-remote-driver:3.14.0" + testCompile "org.seleniumhq.selenium:selenium-api:3.14.0" + testCompile "org.seleniumhq.selenium:selenium-support:3.14.0" + testRuntime "org.seleniumhq.selenium:selenium-chrome-driver:3.14.0" + testRuntime "org.seleniumhq.selenium:selenium-firefox-driver:3.14.0" + + // External config + compile 'org.grails.plugins:external-config:2.0.0' + + // Javascript libraries + compile 'org.webjars:knockout:3.5.1' + + // ALA Plugins + compile group: 'org.grails.plugins', name: 'ala-auth', version: '3.2.2' + compile group: 'org.grails.plugins', name: 'ala-admin-plugin', version: '2.2' + compile group: 'org.grails.plugins', name: 'ala-bootstrap3', version: '3.2.3' + compile group: 'au.org.ala.plugins.grails', name: 'images-client-plugin', version: '1.2' +} + +bootRun { + ignoreExitValue true + jvmArgs( + '-Dspring.output.ansi.enabled=always', + '-noverify', + '-XX:TieredStopAtLevel=1', + '-Xmx1024m') + sourceResources sourceSets.main + String springProfilesActive = 'spring.profiles.active' + systemProperty springProfilesActive, System.getProperty(springProfilesActive) +} + +tasks.withType(GroovyCompile) { + configure(groovyOptions) { + forkOptions.jvmArgs = ['-Xmx1024m'] + } +} + +webdriverBinaries { + chromedriver '2.45.0' + geckodriver '0.24.0' +} + +tasks.withType(Test) { + systemProperty "geb.env", System.getProperty('geb.env') + systemProperty "geb.build.reportsDir", reporting.file("geb/integrationTest") + systemProperty "webdriver.chrome.driver", System.getProperty('webdriver.chrome.driver') + systemProperty "webdriver.gecko.driver", System.getProperty('webdriver.gecko.driver') +} + +assets { + minifyJs = true + minifyCss = true +} + +// Standard ALA import doesn't work with this version +publishing { + repositories { + maven { + name 'Nexus' + url "https://nexus.ala.org.au/content/repositories/${project.version.endsWith('-SNAPSHOT') ? 'snapshots' : 'releases' }" + credentials { + username = System.getenv('TRAVIS_DEPLOY_USERNAME') + password = System.getenv('TRAVIS_DEPLOY_PASSWORD') + } + } + } + publications { + mavenJar(MavenPublication) { + pom.withXml { + def pomNode = asNode() + pomNode.dependencyManagement.replaceNode {} + + // simply remove dependencies without a version + // version-less dependencies are handled with dependencyManagement + // see https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/8 for more complete solutions + pomNode.dependencies.dependency.findAll { + it.version.text().isEmpty() + }.each { + it.replaceNode {} + } + } + from components.web + } + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..f5c617a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,5 @@ +grailsVersion=4.0.5 +gorm.version=7.0.8.RELEASE +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..87b738c 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..5028f28 --- /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-5.6.4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..af6708f --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100755 index 0000000..6d57edc --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@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 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" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/web-app/images/ajax-loader.gif b/grails-app/assets/images/ajax-loader.gif similarity index 100% rename from web-app/images/ajax-loader.gif rename to grails-app/assets/images/ajax-loader.gif diff --git a/grails-app/assets/javascripts/admin.js b/grails-app/assets/javascripts/admin.js new file mode 100644 index 0000000..dd415f0 --- /dev/null +++ b/grails-app/assets/javascripts/admin.js @@ -0,0 +1,3 @@ +//= require /webjars/knockout/3.5.1/knockout.js +//= require jquery.ba-bbq.min.js +//= require utilities.js \ No newline at end of file diff --git a/grails-app/assets/javascripts/browser.js b/grails-app/assets/javascripts/browser.js new file mode 100644 index 0000000..dd415f0 --- /dev/null +++ b/grails-app/assets/javascripts/browser.js @@ -0,0 +1,3 @@ +//= require /webjars/knockout/3.5.1/knockout.js +//= require jquery.ba-bbq.min.js +//= require utilities.js \ No newline at end of file diff --git a/web-app/js/jquery.ba-bbq.min.js b/grails-app/assets/javascripts/jquery.ba-bbq.min.js similarity index 100% rename from web-app/js/jquery.ba-bbq.min.js rename to grails-app/assets/javascripts/jquery.ba-bbq.min.js diff --git a/web-app/js/application.js b/grails-app/assets/javascripts/utilities.js similarity index 99% rename from web-app/js/application.js rename to grails-app/assets/javascripts/utilities.js index 60074ff..b8ad840 100644 --- a/web-app/js/application.js +++ b/grails-app/assets/javascripts/utilities.js @@ -72,4 +72,3 @@ function AjaxLauncher (baseUrl) { list.push(callback); }; } - diff --git a/grails-app/assets/stylesheets/errors.css b/grails-app/assets/stylesheets/errors.css new file mode 100644 index 0000000..1c616d8 --- /dev/null +++ b/grails-app/assets/stylesheets/errors.css @@ -0,0 +1,109 @@ +h1, h2 { + margin: 10px 25px 5px; +} + +h2 { + font-size: 1.1em; +} + +.filename { + font-style: italic; +} + +.exceptionMessage { + margin: 10px; + border: 1px solid #000; + padding: 5px; + background-color: #E9E9E9; +} + +.stack, +.snippet { + margin: 0 25px 10px; +} + +.stack, +.snippet { + border: 1px solid #ccc; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); +} + +/* error details */ +.error-details { + border-top: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + border-bottom: 1px solid #FFAAAA; + -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); + -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); + box-shadow: 0 0 2px rgba(0,0,0,0.2); + background-color:#FFF3F3; + line-height: 1.5; + overflow: hidden; + padding: 5px; + padding-left:25px; +} + +.error-details dt { + clear: left; + float: left; + font-weight: bold; + margin-right: 5px; +} + +.error-details dt:after { + content: ":"; +} + +.error-details dd { + display: block; +} + +/* stack trace */ +.stack { + padding: 5px; + overflow: auto; + height: 150px; +} + +/* code snippet */ +.snippet { + background-color: #fff; + font-family: monospace; +} + +.snippet .line { + display: block; +} + +.snippet .lineNumber { + background-color: #ddd; + color: #999; + display: inline-block; + margin-right: 5px; + padding: 0 3px; + text-align: right; + width: 3em; +} + +.snippet .error { + background-color: #fff3f3; + font-weight: bold; +} + +.snippet .error .lineNumber { + background-color: #faa; + color: #333; + font-weight: bold; +} + +.snippet .line:first-child .lineNumber { + padding-top: 5px; +} + +.snippet .line:last-child .lineNumber { + padding-bottom: 5px; +} \ No newline at end of file diff --git a/web-app/css/specimenbrowser.css b/grails-app/assets/stylesheets/specimenbrowser.css similarity index 93% rename from web-app/css/specimenbrowser.css rename to grails-app/assets/stylesheets/specimenbrowser.css index 7425ab8..6988d55 100644 --- a/web-app/css/specimenbrowser.css +++ b/grails-app/assets/stylesheets/specimenbrowser.css @@ -1,128 +1,128 @@ -.panel-text { margin-top : 15px; font-size: 15px; line-height: 1.5em;} -.panel h2 { line-height: 1.2em; } -.panel h3 { line-height: 1.2em; } - -.space-after { - margin-bottom: 10px; -} - -.space-before { - margin-top: 10px; -} - -.large-space-after { - margin-bottom: 20px; -} - -.large-space-before { - margin-top: 20px; -} - -.center {text-align: center} - -.clickable { - cursor: pointer; - /*text-decoration: underline;*/ - color: #007fb6; -} - -ul { - list-style: none; -} - -.clickable:hover, -.clickable:focus { - color: #00638d; - text-decoration: underline; -} - -#imagesList { - margin:0; -} - -.imgCon { - display: inline-block; - /*margin-right: 8px;*/ - text-align: center; - line-height: 1.3em; - background-color: #DDD; - color: #DDD; - /*padding: 5px;*/ - /*margin-bottom: 8px;*/ - margin: 2px 0 2px 0; - position: relative; -} - -.imgCon .meta { - opacity: 0.7; - position: absolute; - bottom: 0; - left: 0; - right: 0; - overflow: hidden; - text-align: left; - padding: 4px 6px 2px 8px; -} - -.imgCon .full { - color: white; - background-color: black; - display: none; -} - -.imgCon .brief { - color: black; - background-color: white; -} - -.imgCon .hover-target { - display: none; -} - -.imgCon:hover .full { - display: inline-block; -} - -.imgCon:hover .brief { - display: none; -} - -#taxonomyFacet .level0 { - margin-left: 0; -} - -#taxonomyFacet .level1 { - margin-left: 4px; -} - -#taxonomyFacet .level2 { - margin-left: 8px; -} - -#taxonomyFacet .level3 { - margin-left: 12px; -} - -#taxonomyFacet .level4 { - margin-left: 16px; -} - -#taxonomyFacet .level5 { - margin-left: 20px; -} - -#taxonomyFacet .level6 { - margin-left: 24px; -} - -#taxonomyFacet .level7 { - margin-left: 28px; -} - -#taxonomyFacet .level8 { - margin-left: 32px; -} - -#imageViewer { - height: 600px; -} +.panel-text { margin-top : 15px; font-size: 15px; line-height: 1.5em;} +.panel h2 { line-height: 1.2em; } +.panel h3 { line-height: 1.2em; } + +.space-after { + margin-bottom: 10px; +} + +.space-before { + margin-top: 10px; +} + +.large-space-after { + margin-bottom: 20px; +} + +.large-space-before { + margin-top: 20px; +} + +.center {text-align: center} + +.clickable { + cursor: pointer; + /*text-decoration: underline;*/ + color: #007fb6; +} + +ul { + list-style: none; +} + +.clickable:hover, +.clickable:focus { + color: #00638d; + text-decoration: underline; +} + +#imagesList { + margin:0; +} + +.imgCon { + display: inline-block; + /*margin-right: 8px;*/ + text-align: center; + line-height: 1.3em; + background-color: #DDD; + color: #DDD; + /*padding: 5px;*/ + /*margin-bottom: 8px;*/ + margin: 2px 0 2px 0; + position: relative; +} + +.imgCon .meta { + opacity: 0.7; + position: absolute; + bottom: 0; + left: 0; + right: 0; + overflow: hidden; + text-align: left; + padding: 4px 6px 2px 8px; +} + +.imgCon .full { + color: white; + background-color: black; + display: none; +} + +.imgCon .brief { + color: black; + background-color: white; +} + +.imgCon .hover-target { + display: none; +} + +.imgCon:hover .full { + display: inline-block; +} + +.imgCon:hover .brief { + display: none; +} + +#taxonomyFacet .level0 { + margin-left: 0; +} + +#taxonomyFacet .level1 { + margin-left: 4px; +} + +#taxonomyFacet .level2 { + margin-left: 8px; +} + +#taxonomyFacet .level3 { + margin-left: 12px; +} + +#taxonomyFacet .level4 { + margin-left: 16px; +} + +#taxonomyFacet .level5 { + margin-left: 20px; +} + +#taxonomyFacet .level6 { + margin-left: 24px; +} + +#taxonomyFacet .level7 { + margin-left: 28px; +} + +#taxonomyFacet .level8 { + margin-left: 32px; +} + +#imageViewer { + height: 600px; +} diff --git a/grails-app/assets/stylesheets/viewer.css b/grails-app/assets/stylesheets/viewer.css new file mode 100644 index 0000000..756c495 --- /dev/null +++ b/grails-app/assets/stylesheets/viewer.css @@ -0,0 +1,5 @@ +/* + * CSS and extensions for the image viewer + * + * + */ \ No newline at end of file diff --git a/grails-app/conf/ApplicationResources.groovy b/grails-app/conf/ApplicationResources.groovy deleted file mode 100644 index 23bac5b..0000000 --- a/grails-app/conf/ApplicationResources.groovy +++ /dev/null @@ -1,14 +0,0 @@ -modules = { - application { - resource url:'js/application.js' - resource url:'css/specimenbrowser.css' - } - - knockout { - resource 'js/knockout-3.0.0.js' - } - - bbq { - resource 'js/jquery.ba-bbq.min.js' - } -} \ No newline at end of file diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy deleted file mode 100644 index 6db0c31..0000000 --- a/grails-app/conf/BuildConfig.groovy +++ /dev/null @@ -1,48 +0,0 @@ -grails.servlet.version = "2.5" // Change depending on target container compliance (2.5 or 3.0) -grails.project.class.dir = "target/classes" -grails.project.test.class.dir = "target/test-classes" -grails.project.test.reports.dir = "target/test-reports" -grails.project.target.level = 1.6 -grails.project.source.level = 1.6 -//grails.project.war.file = "target/${appName}-${appVersion}.war" - -//grails.plugin.location."images-client-plugin" = "../images-client-plugin" -// uncomment (and adjust settings) to fork the JVM to isolate classpaths -grails.project.fork = [ - test: false, - run: false, - war: false, - console: false -] - -grails.project.dependency.resolver = "maven" - -grails.project.dependency.resolution = { - // inherit Grails' default dependencies - inherits("global") { - // specify dependency exclusions here; for example, uncomment this to disable ehcache: - // excludes 'ehcache' - } - log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose' - checksums true // Whether to verify checksums on resolve - legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility - - repositories { - mavenLocal() - mavenRepo("https://nexus.ala.org.au/content/groups/public/"){ - updatePolicy 'always' - } - } - - dependencies { - - } - - plugins { - runtime ":ala-bootstrap2:2.2" - runtime ":images-client-plugin:0.5.3" - compile ':cache:1.1.8' - compile ':ala-auth:1.3.1' - build ':tomcat:7.0.54' - } -} diff --git a/grails-app/conf/Config.groovy b/grails-app/conf/Config.groovy deleted file mode 100644 index 11139e3..0000000 --- a/grails-app/conf/Config.groovy +++ /dev/null @@ -1,163 +0,0 @@ -/******************************************************************************\ - * CONFIG MANAGEMENT - \******************************************************************************/ -def appName = 'specimenbrowser' -def ENV_NAME = "${appName.toUpperCase()}_CONFIG" -default_config = "/data/${appName}/config/${appName}-config.properties" -if(!grails.config.locations || !(grails.config.locations instanceof List)) { - grails.config.locations = [] -} -if(System.getenv(ENV_NAME) && new File(System.getenv(ENV_NAME)).exists()) { - println "[${appName}] Including configuration file specified in environment: " + System.getenv(ENV_NAME); - grails.config.locations.add "file:" + System.getenv(ENV_NAME) -} else if(System.getProperty(ENV_NAME) && new File(System.getProperty(ENV_NAME)).exists()) { - println "[${appName}] Including configuration file specified on command line: " + System.getProperty(ENV_NAME); - grails.config.locations.add "file:" + System.getProperty(ENV_NAME) -} else if(new File(default_config).exists()) { - println "[${appName}] Including default configuration file: " + default_config; - grails.config.locations.add "file:" + default_config -} else { - println "[${appName}] No external configuration file defined." -} -println "[${appName}] (*) grails.config.locations = ${grails.config.locations}" - -grails.project.groupId = appName // change this to alter the default package name and Maven publishing destination -grails.mime.file.extensions = true // enables the parsing of file extensions from URLs into the request format -grails.mime.use.accept.header = false -grails.mime.types = [ - all: '*/*', - atom: 'application/atom+xml', - css: 'text/css', - csv: 'text/csv', - form: 'application/x-www-form-urlencoded', - html: ['text/html','application/xhtml+xml'], - js: 'text/javascript', - json: ['application/json', 'text/json'], - multipartForm: 'multipart/form-data', - rss: 'application/rss+xml', - text: 'text/plain', - xml: ['text/xml', 'application/xml'] -] - -// URL Mapping Cache Max Size, defaults to 5000 -//grails.urlmapping.cache.maxsize = 1000 - -// What URL patterns should be processed by the resources plugin -grails.resources.adhoc.patterns = ['/images/*', '/css/*', '/js/*', '/plugins/*'] - -/******************************************************************************\ - * RELOADABLE CONFIG - \******************************************************************************/ -reloadable.cfgs = ["file:/data/${appName}/config/${appName}-config.properties"] - -/******************************************************************************\ - * EXTERNAL SERVERS - \******************************************************************************/ -if (!bie.baseURL) { - bie.baseURL = "https://bie.ala.org.au" -} -if (!bie.searchPath) { - bie.searchPath = "/search" -} -if (!biocache.baseURL) { - biocache.baseURL = "https://biocache.ala.org.au" -} -if(!biocacheServicesUrl){ - biocacheServicesUrl = "https://biocache-ws.ala.org.au/ws" -} -if(!collectory.baseURL){ - collectory.baseURL = "https://collections.ala.org.au" -} -if(!collectory.servicesURL){ - collectory.servicesURL = "https://collections.ala.org.au/ws" -} -if (!spatial.baseURL) { - spatial.baseURL = "https://spatial.ala.org.au" -} -if (!ala.baseURL) { - ala.baseURL = "https://www.ala.org.au" -} -if (!ala.image.service.url) { - ala.image.service.url = "https://images.ala.org.au" -} - -// The default codec used to encode data with ${} -grails.views.default.codec = "none" // none, html, base64 -grails.views.gsp.encoding = "UTF-8" -grails.converters.encoding = "UTF-8" -// enable Sitemesh preprocessing of GSP pages -grails.views.gsp.sitemesh.preprocess = true -// scaffolding templates configuration -grails.scaffolding.templates.domainSuffix = 'Instance' - -// Set to false to use the new Grails 1.2 JSONBuilder in the render method -grails.json.legacy.builder = false -// enabled native2ascii conversion of i18n properties files -grails.enable.native2ascii = true -// packages to include in Spring bean scanning -grails.spring.bean.packages = [] -// whether to disable processing of multi part requests -grails.web.disable.multipart=false - -// request parameters to mask when logging exceptions -grails.exceptionresolver.params.exclude = ['password'] - -// configure auto-caching of queries by default (if false you can cache individual queries with 'cache: true') -grails.hibernate.cache.queries = false - -environments { - development { - grails.logging.jul.usebridge = true - grails.serverURL = "http://devt.ala.org.au:8080/specimenbrowser" -// grails.context = '' - } - production { - grails.logging.jul.usebridge = false - // TODO: grails.serverURL = "http://www.changeme.com" - } -} - -// log4j configuration -log4j = { - // Example of changing the log pattern for the default console appender: - // - //appenders { - // console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n') - //} - - error 'org.codehaus.groovy.grails.web.servlet', // controllers - 'org.codehaus.groovy.grails.web.pages', // GSP - 'org.codehaus.groovy.grails.web.sitemesh', // layouts - 'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping - 'org.codehaus.groovy.grails.web.mapping', // URL mapping - 'org.codehaus.groovy.grails.commons', // core / classloading - 'org.codehaus.groovy.grails.plugins', // plugins - 'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration - 'org.springframework', - 'org.hibernate', - 'net.sf.ehcache.hibernate' -} - -// Uncomment and edit the following lines to start using Grails encoding & escaping improvements - -/* remove this line -// GSP settings -grails { - views { - gsp { - encoding = 'UTF-8' - htmlcodec = 'xml' // use xml escaping instead of HTML4 escaping - codecs { - expression = 'html' // escapes values inside null - scriptlet = 'none' // escapes output from scriptlets in GSPs - taglib = 'none' // escapes output from taglibs - staticparts = 'none' // escapes output from static template parts - } - } - // escapes all not-encoded output at final stage of outputting - filteringCodecForContentType { - //'text/html' = 'html' - } - } -} -remove this line */ diff --git a/grails-app/conf/DataSource.groovy b/grails-app/conf/DataSource.groovy deleted file mode 100644 index 3d6b94a..0000000 --- a/grails-app/conf/DataSource.groovy +++ /dev/null @@ -1,2 +0,0 @@ -dataSource { -} diff --git a/grails-app/conf/application.yml b/grails-app/conf/application.yml new file mode 100644 index 0000000..38f6d00 --- /dev/null +++ b/grails-app/conf/application.yml @@ -0,0 +1,187 @@ +--- +grails: + profile: web + config: + locations: + - file:///data/specimenbrowser/config/specimenbrowser-config.properties + - file:///data/specimenbrowser/config/specimenbrowser-config.yml + - file:///data/specimenbrowser/config/specimenbrowser-config.groovy + codegen: + defaultPackage: au.org.ala.specimenbrowser + gorm: + reactor: + # Whether to translate GORM events into Reactor events + # Disabled by default for performance reasons + events: false +info: + app: + name: '@info.app.name@' + version: '@info.app.version@' + grailsVersion: '@info.app.grailsVersion@' +spring: + jmx: + unique-names: true + main: + banner-mode: "off" + groovy: + template: + check-template-location: false + devtools: + restart: + additional-exclude: + - '*.gsp' + - '**/*.gsp' + - '*.gson' + - '**/*.gson' + - 'logback.groovy' + - '*.properties' +management: + endpoints: + enabled-by-default: false + +--- +grails: + mime: + disable: + accept: + header: + userAgents: + - Gecko + - WebKit + - Presto + - Trident + types: + all: '*/*' + atom: application/atom+xml + css: text/css + csv: text/csv + form: application/x-www-form-urlencoded + html: + - text/html + - application/xhtml+xml + js: text/javascript + json: + - application/json + - text/json + multipartForm: multipart/form-data + pdf: application/pdf + rss: application/rss+xml + text: text/plain + hal: + - application/hal+json + - application/hal+xml + xml: + - text/xml + - application/xml + urlmapping: + cache: + maxsize: 1000 + controllers: + defaultScope: singleton + converters: + encoding: UTF-8 + views: + default: + codec: html + gsp: + encoding: UTF-8 + htmlcodec: xml + codecs: + expression: html + scriptlet: html + taglib: none + staticparts: none +management: + endpoints: + jmx: + unique-names: true + +--- +hibernate: + cache: + queries: false + use_second_level_cache: false + use_query_cache: false +dataSource: + pooled: true + jmxExport: true + driverClassName: org.h2.Driver + username: sa + password: '' + +environments: + development: + dataSource: + dbCreate: update + url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + test: + dataSource: + dbCreate: update + url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + production: + dataSource: + dbCreate: none + url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE + properties: + jmxEnabled: true + initialSize: 5 + maxActive: 50 + minIdle: 5 + maxIdle: 25 + maxWait: 10000 + maxAge: 600000 + timeBetweenEvictionRunsMillis: 5000 + minEvictableIdleTimeMillis: 60000 + validationQuery: SELECT 1 + validationQueryTimeout: 3 + validationInterval: 15000 + testOnBorrow: true + testWhileIdle: true + testOnReturn: false + jdbcInterceptors: ConnectionState + defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED +--- +grails: + serverURL: https://specimens.ala.org.au +bie: + baseURL: https://bie.ala.org.au + searchPath: /search +biocache: + baseURL: https://biocache.ala.org.au + servicesUrl: https://biocache-ws.ala.org.au/ws/ +collectory: + baseURL: https://collections.ala.org.au + servicesUrl: https://collections.ala.org.au/ws/ + resourceMapping: + - prefix: dr + path: dataResource + - prefix: co + path: collection + - prefix: in + path: institution + - prefix: dh + path: dataHub + - prefix: dp + path: dataProvider +spatial: + baseURL: https://spatial.ala.org.au +ala: + baseURL: https://www.ala.org.au + image: + service: + url: https://images.ala.org.au +security: + cas: + appServerName: https://specimens.ala.org.au + casServerName: https://auth.ala.org.au + uriFilterPattern: /admin.*,/alaAdmin.* +skin: + layout: main + fluidLayout: true + orgNameLong: Atlas of Living Australia +specimenbrowser: + data: + url: file:///data/specimenbrowser/config/data.json +headerAndFooter: + baseURL: https://www.ala.org.au/commonui-bs3-2019 + version: 2 diff --git a/grails-app/conf/logback.groovy b/grails-app/conf/logback.groovy new file mode 100644 index 0000000..b835215 --- /dev/null +++ b/grails-app/conf/logback.groovy @@ -0,0 +1,37 @@ +import grails.util.BuildSettings +import grails.util.Environment +import org.springframework.boot.logging.logback.ColorConverter +import org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter + +import java.nio.charset.StandardCharsets + +conversionRule 'clr', ColorConverter +conversionRule 'wex', WhitespaceThrowableProxyConverter + +// See http://logback.qos.ch/manual/groovy.html for details on configuration +appender('STDOUT', ConsoleAppender) { + encoder(PatternLayoutEncoder) { + charset = StandardCharsets.UTF_8 + + pattern = + '%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} ' + // Date + '%clr(%5p) ' + // Log level + '%clr(---){faint} %clr([%15.15t]){faint} ' + // Thread + '%clr(%-40.40logger{39}){cyan} %clr(:){faint} ' + // Logger + '%m%n%wex' // Message + } +} + +def targetDir = BuildSettings.TARGET_DIR +if (Environment.isDevelopmentMode() && targetDir != null) { + appender("FULL_STACKTRACE", FileAppender) { + file = "${targetDir}/stacktrace.log" + append = true + encoder(PatternLayoutEncoder) { + charset = StandardCharsets.UTF_8 + pattern = "%level %logger - %msg%n" + } + } + logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false) +} +root(ERROR, ['STDOUT']) diff --git a/grails-app/controllers/au/org/ala/specimenbrowser/AdminController.groovy b/grails-app/controllers/au/org/ala/specimenbrowser/AdminController.groovy index 4b39620..d109554 100644 --- a/grails-app/controllers/au/org/ala/specimenbrowser/AdminController.groovy +++ b/grails-app/controllers/au/org/ala/specimenbrowser/AdminController.groovy @@ -1,61 +1,19 @@ package au.org.ala.specimenbrowser -import grails.util.Environment -import org.springframework.core.io.support.PathMatchingResourcePatternResolver +import au.org.ala.web.AlaSecured +import au.org.ala.web.CASRoles +@AlaSecured(CASRoles.ROLE_ADMIN) class AdminController { + def resourceService def index() {} - def tools() {} - def counts() {} - - def settings() { - def settings = [] - def config = grailsApplication.config.flatten() - ['ala.baseURL','grails.serverURL','grails.config.locations','collectory.baseURL', - 'headerAndFooter.baseURL','biocacheServicesUrl','collectory.servicesURL' - ].each { - settings << [key: it, value: config[it], comment: ''] - } - [settings: settings] - } - def reloadConfig = { - // clear any cached external config - //cacheService.clear() - - // reload system config - def resolver = new PathMatchingResourcePatternResolver() - def resource = resolver.getResource(grailsApplication.config.reloadable.cfgs[0]) - def stream = null + def counts() {} - try { - stream = resource.getInputStream() - ConfigSlurper configSlurper = new ConfigSlurper(Environment.current.name) - if(resource.filename.endsWith('.groovy')) { - def newConfig = configSlurper.parse(stream.text) - grailsApplication.getConfig().merge(newConfig) - } - else if(resource.filename.endsWith('.properties')) { - def props = new Properties() - props.load(stream) - def newConfig = configSlurper.parse(props) - grailsApplication.getConfig().merge(newConfig) - } - flash.message = "Config reloaded from ${grailsApplication.config.reloadable.cfgs[0]}." - render 'done' - } - catch (FileNotFoundException fnf) { - println "No external config to reload configuration. Looking for ${grailsApplication.config.reloadable.cfgs[0]}" - render "No external config to reload configuration. Looking for ${grailsApplication.config.reloadable.cfgs[0]}" - } - catch (Exception gre) { - println "Unable to reload configuration. Please correct problem and try again: " + gre.getMessage() - render "Unable to reload configuration - " + gre.getMessage() - } - finally { - stream?.close() - } + def reloadResources() { + resourceService.buildResources() + flash.message = "Resource configuration reloaded" + redirect controller: 'admin', action: 'index' } - } diff --git a/grails-app/controllers/au/org/ala/specimenbrowser/ViewController.groovy b/grails-app/controllers/au/org/ala/specimenbrowser/ViewController.groovy index f1f910e..9ffe2fe 100644 --- a/grails-app/controllers/au/org/ala/specimenbrowser/ViewController.groovy +++ b/grails-app/controllers/au/org/ala/specimenbrowser/ViewController.groovy @@ -1,24 +1,17 @@ package au.org.ala.specimenbrowser -import grails.converters.JSON +import grails.config.Config +import grails.core.support.GrailsConfigurationAware import groovy.json.JsonOutput import groovy.json.JsonSlurper -class ViewController { +class ViewController implements GrailsConfigurationAware { + def resourceService - def grailsApplication + URL biocacheServicesUrl def homePage(){ - def collectionsData = [] - def md = new File("/data/specimenbrowser/config/data.json")?.text - def js = new JsonSlurper() - def collectionsToRender = js.parseText(md) - collectionsToRender.each { collection -> - def collectionMetadata = js.parseText(new URL(grailsApplication.config.collectory.servicesURL + "/collection/" + collection.uid).text) - collectionMetadata.put("displayCollectionImage", collection.imageUrl) - collectionsData << collectionMetadata - } - [collectionsData: collectionsData] + [collectionsData: resourceService.resources] } def view(String id, String recordId) { @@ -27,31 +20,37 @@ class ViewController { def auxData(){ def js = new JsonSlurper() - def json = js.parseText(new URL(grailsApplication.config.biocacheServicesUrl + "/occurrence/" + params.recordId).text) - def title = "Collection: " + json.processed.attribution.collectionName - def data = [ - "Scientific name": json.raw.classification.scientificName, - "Type status": json.raw.identification.typeStatus?:"", - "Catalog Number": json.raw.occurrence.catalogNumber?:"", - "Preparations": json.raw.occurrence.preparations?:"", - "Sex": json.raw.occurrence.sex?:"", - "Recorded by": json.raw.occurrence.recordedBy?:"", - "Photographer": json.raw.occurrence.photographer?:"", - "State": json.processed.location.stateProvince?:"", - "Country": json.processed.location.country?:"" - ] + def json = js.parse(new URL(biocacheServicesUrl, "occurrence/" + params.recordId)) + def data = [:] + def title + if (!json) { + title = "Unable to retrieve specimen data" + } else { + title = "Collection: " + json.processed.attribution.collectionName + data = [ + "Scientific name": json.raw.classification.scientificName, + "Type status" : json.raw.identification.typeStatus ?: "", + "Catalog Number" : json.raw.occurrence.catalogNumber ?: "", + "Preparations" : json.raw.occurrence.preparations ?: "", + "Sex" : json.raw.occurrence.sex ?: "", + "Recorded by" : json.raw.occurrence.recordedBy ?: "", + "Photographer" : json.raw.occurrence.photographer ?: "", + "State" : json.processed.location.stateProvince ?: "", + "Country" : json.processed.location.country ?: "" + ] - if(json.processed.location.decimalLatitude && json.processed.location.decimalLongitude){ - data.put("Coordinates", json.processed.location.decimalLatitude + " " + json.processed.location.decimalLongitude) - } - if(json.raw.location.locality){ - data.put("Locality", json.raw.location.locality) - } - if(json.processed.location.stateProvince){ - data.put("State", json.processed.location.stateProvince) - } - if(json.processed.location.country){ - data.put("Country", json.processed.location.country) + if (json.processed.location.decimalLatitude && json.processed.location.decimalLongitude) { + data.put("Coordinates", json.processed.location.decimalLatitude + " " + json.processed.location.decimalLongitude) + } + if (json.raw.location.locality) { + data.put("Locality", json.raw.location.locality) + } + if (json.processed.location.stateProvince) { + data.put("State", json.processed.location.stateProvince) + } + if (json.processed.location.country) { + data.put("Country", json.processed.location.country) + } } def model = [title:title, data:data, link:grailsApplication.config.biocache.baseURL + "/occurrence/" + params.recordId, linkText:"View full record details"] @@ -63,4 +62,9 @@ class ViewController { response.setContentType("application/json") render output } + + @Override + void setConfiguration(Config config) { + biocacheServicesUrl = new URL(config.getRequiredProperty("biocache.servicesUrl")) + } } diff --git a/grails-app/conf/UrlMappings.groovy b/grails-app/controllers/specimenbrowser/UrlMappings.groovy similarity index 57% rename from grails-app/conf/UrlMappings.groovy rename to grails-app/controllers/specimenbrowser/UrlMappings.groovy index d926e15..4c20d7a 100644 --- a/grails-app/conf/UrlMappings.groovy +++ b/grails-app/controllers/specimenbrowser/UrlMappings.groovy @@ -1,7 +1,8 @@ -class UrlMappings { +package specimenbrowser - static mappings = { +class UrlMappings { + static mappings = { "/browse/$id?"{ controller = 'browse' action = 'index' @@ -15,15 +16,17 @@ class UrlMappings { } } - "/$controller/$action?/$id?"{ - constraints { - // apply constraints here - } - } - "/"(controller: 'view', action: 'homePage') - "/auxData/$recordId"(controller: 'view', action: 'auxData') + "/"(controller: 'view', action: 'homePage') + "/view/auxData/$recordId"(controller: 'view', action: 'auxData') "/view/$id"(controller: 'view', action: 'view') - "500"(view:'/error') - } + "/$controller/$action?/$id?"{ + constraints { + // apply constraints here + } + } + + "500"(view:'/error') + "404"(view:'/notFound') + } } diff --git a/grails-app/i18n/messages.properties b/grails-app/i18n/messages.properties index 0c9d7ee..b045136 100644 --- a/grails-app/i18n/messages.properties +++ b/grails-app/i18n/messages.properties @@ -53,3 +53,4 @@ typeMismatch.java.lang.Long=Property {0} must be a valid number typeMismatch.java.lang.Short=Property {0} must be a valid number typeMismatch.java.math.BigDecimal=Property {0} must be a valid number typeMismatch.java.math.BigInteger=Property {0} must be a valid number +typeMismatch=Property {0} is type-mismatched diff --git a/grails-app/i18n/messages_cs_CZ.properties b/grails-app/i18n/messages_cs.properties similarity index 98% rename from grails-app/i18n/messages_cs_CZ.properties rename to grails-app/i18n/messages_cs.properties index c617dca..7345531 100644 --- a/grails-app/i18n/messages_cs_CZ.properties +++ b/grails-app/i18n/messages_cs.properties @@ -1,55 +1,55 @@ -default.doesnt.match.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neodpovídá požadovanému vzoru [{3}] -default.invalid.url.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní URL -default.invalid.creditCard.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní číslo kreditní karty -default.invalid.email.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní emailová adresa -default.invalid.range.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] -default.invalid.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] -default.invalid.max.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální povolenou hodnotu [{3}] -default.invalid.min.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální povolená hodnota [{3}] -default.invalid.max.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální velikost [{3}] -default.invalid.min.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální velikost [{3}] -default.invalid.validator.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neprošla validací -default.not.inlist.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není obsažena v seznamu [{3}] -default.blank.message=Položka [{0}] třídy [{1}] nemůže být prázdná -default.not.equal.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] nemůže být stejná jako [{3}] -default.null.message=Položka [{0}] třídy [{1}] nemůže být prázdná -default.not.unique.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] musí být unikátní - -default.paginate.prev=Předcházející -default.paginate.next=Následující -default.boolean.true=Pravda -default.boolean.false=Nepravda -default.date.format=dd. MM. yyyy HH:mm:ss z -default.number.format=0 - -default.created.message={0} {1} vytvořeno -default.updated.message={0} {1} aktualizováno -default.deleted.message={0} {1} smazáno -default.not.deleted.message={0} {1} nelze smazat -default.not.found.message={0} nenalezen s id {1} -default.optimistic.locking.failure=Jiný uživatel aktualizoval záznam {0}, právě když byl vámi editován - -default.home.label=Domů -default.list.label={0} Seznam -default.add.label=Přidat {0} -default.new.label=Nový {0} -default.create.label=Vytvořit {0} -default.show.label=Ukázat {0} -default.edit.label=Editovat {0} - -default.button.create.label=Vytvoř -default.button.edit.label=Edituj -default.button.update.label=Aktualizuj -default.button.delete.label=Smaž -default.button.delete.confirm.message=Jste si jistý? - -# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) -typeMismatch.java.net.URL=Položka {0} musí být validní URL -typeMismatch.java.net.URI=Položka {0} musí být validní URI -typeMismatch.java.util.Date=Položka {0} musí být validní datum -typeMismatch.java.lang.Double=Položka {0} musí být validní desetinné číslo -typeMismatch.java.lang.Integer=Položka {0} musí být validní číslo -typeMismatch.java.lang.Long=Položka {0} musí být validní číslo -typeMismatch.java.lang.Short=Položka {0} musí být validní číslo -typeMismatch.java.math.BigDecimal=Položka {0} musí být validní číslo -typeMismatch.java.math.BigInteger=Položka {0} musí být validní číslo \ No newline at end of file +default.doesnt.match.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neodpovídá požadovanému vzoru [{3}] +default.invalid.url.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní URL +default.invalid.creditCard.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní číslo kreditní karty +default.invalid.email.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není validní emailová adresa +default.invalid.range.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není v povoleném rozmezí od [{3}] do [{4}] +default.invalid.max.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální povolenou hodnotu [{3}] +default.invalid.min.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální povolená hodnota [{3}] +default.invalid.max.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] překračuje maximální velikost [{3}] +default.invalid.min.size.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] je menší než minimální velikost [{3}] +default.invalid.validator.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] neprošla validací +default.not.inlist.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] není obsažena v seznamu [{3}] +default.blank.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.equal.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] nemůže být stejná jako [{3}] +default.null.message=Položka [{0}] třídy [{1}] nemůže být prázdná +default.not.unique.message=Položka [{0}] třídy [{1}] o hodnotě [{2}] musí být unikátní + +default.paginate.prev=Předcházející +default.paginate.next=Následující +default.boolean.true=Pravda +default.boolean.false=Nepravda +default.date.format=dd. MM. yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} vytvořeno +default.updated.message={0} {1} aktualizováno +default.deleted.message={0} {1} smazáno +default.not.deleted.message={0} {1} nelze smazat +default.not.found.message={0} nenalezen s id {1} +default.optimistic.locking.failure=Jiný uživatel aktualizoval záznam {0}, právě když byl vámi editován + +default.home.label=Domů +default.list.label={0} Seznam +default.add.label=Přidat {0} +default.new.label=Nový {0} +default.create.label=Vytvořit {0} +default.show.label=Ukázat {0} +default.edit.label=Editovat {0} + +default.button.create.label=Vytvoř +default.button.edit.label=Edituj +default.button.update.label=Aktualizuj +default.button.delete.label=Smaž +default.button.delete.confirm.message=Jste si jistý? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Položka {0} musí být validní URL +typeMismatch.java.net.URI=Položka {0} musí být validní URI +typeMismatch.java.util.Date=Položka {0} musí být validní datum +typeMismatch.java.lang.Double=Položka {0} musí být validní desetinné číslo +typeMismatch.java.lang.Integer=Položka {0} musí být validní číslo +typeMismatch.java.lang.Long=Položka {0} musí být validní číslo +typeMismatch.java.lang.Short=Položka {0} musí být validní číslo +typeMismatch.java.math.BigDecimal=Položka {0} musí být validní číslo +typeMismatch.java.math.BigInteger=Položka {0} musí být validní číslo diff --git a/grails-app/i18n/messages_de.properties b/grails-app/i18n/messages_de.properties index a942358..0f7bfe9 100644 --- a/grails-app/i18n/messages_de.properties +++ b/grails-app/i18n/messages_de.properties @@ -1,55 +1,55 @@ -default.doesnt.match.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] entspricht nicht dem vorgegebenen Muster [{3}] -default.invalid.url.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige URL -default.invalid.creditCard.message=Das Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige Kreditkartennummer -default.invalid.email.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige E-Mail Adresse -default.invalid.range.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] -default.invalid.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] -default.invalid.max.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist größer als der Höchstwert von [{3}] -default.invalid.min.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist kleiner als der Mindestwert von [{3}] -default.invalid.max.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] übersteigt den Höchstwert von [{3}] -default.invalid.min.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] unterschreitet den Mindestwert von [{3}] -default.invalid.validator.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist ungültig -default.not.inlist.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht in der Liste [{3}] enthalten. -default.blank.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht leer sein -default.not.equal.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nicht gleich [{3}] sein -default.null.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht null sein -default.not.unique.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nur einmal vorkommen - -default.paginate.prev=Vorherige -default.paginate.next=Nächste -default.boolean.true=Wahr -default.boolean.false=Falsch -default.date.format=dd.MM.yyyy HH:mm:ss z -default.number.format=0 - -default.created.message={0} {1} wurde angelegt -default.updated.message={0} {1} wurde geändert -default.deleted.message={0} {1} wurde gelöscht -default.not.deleted.message={0} {1} konnte nicht gelöscht werden -default.not.found.message={0} mit der id {1} wurde nicht gefunden -default.optimistic.locking.failure=Ein anderer Benutzer hat das {0} Object geändert während Sie es bearbeitet haben - -default.home.label=Home -default.list.label={0} Liste -default.add.label={0} hinzufügen -default.new.label={0} anlegen -default.create.label={0} anlegen -default.show.label={0} anzeigen -default.edit.label={0} bearbeiten - -default.button.create.label=Anlegen -default.button.edit.label=Bearbeiten -default.button.update.label=Aktualisieren -default.button.delete.label=Löschen -default.button.delete.confirm.message=Sind Sie sicher? - -# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) -typeMismatch.java.net.URL=Die Eigenschaft {0} muss eine gültige URL sein -typeMismatch.java.net.URI=Die Eigenschaft {0} muss eine gültige URI sein -typeMismatch.java.util.Date=Die Eigenschaft {0} muss ein gültiges Datum sein -typeMismatch.java.lang.Double=Die Eigenschaft {0} muss eine gültige Zahl sein -typeMismatch.java.lang.Integer=Die Eigenschaft {0} muss eine gültige Zahl sein -typeMismatch.java.lang.Long=Die Eigenschaft {0} muss eine gültige Zahl sein -typeMismatch.java.lang.Short=Die Eigenschaft {0} muss eine gültige Zahl sein -typeMismatch.java.math.BigDecimal=Die Eigenschaft {0} muss eine gültige Zahl sein -typeMismatch.java.math.BigInteger=Die Eigenschaft {0} muss eine gültige Zahl sein \ No newline at end of file +default.doesnt.match.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] entspricht nicht dem vorgegebenen Muster [{3}] +default.invalid.url.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige URL +default.invalid.creditCard.message=Das Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige Kreditkartennummer +default.invalid.email.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist keine gültige E-Mail Adresse +default.invalid.range.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht im Wertebereich von [{3}] bis [{4}] +default.invalid.max.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist größer als der Höchstwert von [{3}] +default.invalid.min.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist kleiner als der Mindestwert von [{3}] +default.invalid.max.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] übersteigt den Höchstwert von [{3}] +default.invalid.min.size.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] unterschreitet den Mindestwert von [{3}] +default.invalid.validator.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist ungültig +default.not.inlist.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] ist nicht in der Liste [{3}] enthalten. +default.blank.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht leer sein +default.not.equal.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nicht gleich [{3}] sein +default.null.message=Die Eigenschaft [{0}] des Typs [{1}] darf nicht null sein +default.not.unique.message=Die Eigenschaft [{0}] des Typs [{1}] mit dem Wert [{2}] darf nur einmal vorkommen + +default.paginate.prev=Vorherige +default.paginate.next=Nächste +default.boolean.true=Wahr +default.boolean.false=Falsch +default.date.format=dd.MM.yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} wurde angelegt +default.updated.message={0} {1} wurde geändert +default.deleted.message={0} {1} wurde gelöscht +default.not.deleted.message={0} {1} konnte nicht gelöscht werden +default.not.found.message={0} mit der id {1} wurde nicht gefunden +default.optimistic.locking.failure=Ein anderer Benutzer hat das {0} Object geändert während Sie es bearbeitet haben + +default.home.label=Home +default.list.label={0} Liste +default.add.label={0} hinzufügen +default.new.label={0} anlegen +default.create.label={0} anlegen +default.show.label={0} anzeigen +default.edit.label={0} bearbeiten + +default.button.create.label=Anlegen +default.button.edit.label=Bearbeiten +default.button.update.label=Aktualisieren +default.button.delete.label=Löschen +default.button.delete.confirm.message=Sind Sie sicher? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Die Eigenschaft {0} muss eine gültige URL sein +typeMismatch.java.net.URI=Die Eigenschaft {0} muss eine gültige URI sein +typeMismatch.java.util.Date=Die Eigenschaft {0} muss ein gültiges Datum sein +typeMismatch.java.lang.Double=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Integer=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Long=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.lang.Short=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigDecimal=Die Eigenschaft {0} muss eine gültige Zahl sein +typeMismatch.java.math.BigInteger=Die Eigenschaft {0} muss eine gültige Zahl sein diff --git a/grails-app/i18n/messages_fr.properties b/grails-app/i18n/messages_fr.properties index b1d665c..5572164 100644 --- a/grails-app/i18n/messages_fr.properties +++ b/grails-app/i18n/messages_fr.properties @@ -1,19 +1,19 @@ -default.doesnt.match.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne correspond pas au pattern [{3}] -default.invalid.url.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une URL valide -default.invalid.creditCard.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas un numéro de carte de crédit valide -default.invalid.email.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une adresse e-mail valide -default.invalid.range.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] -default.invalid.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] -default.invalid.max.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] -default.invalid.min.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] -default.invalid.max.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] -default.invalid.min.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] -default.invalid.validator.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas valide -default.not.inlist.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne fait pas partie de la liste [{3}] -default.blank.message=La propriété [{0}] de la classe [{1}] ne peut pas être vide -default.not.equal.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne peut pas être égale à [{3}] -default.null.message=La propriété [{0}] de la classe [{1}] ne peut pas être nulle -default.not.unique.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] doit être unique - -default.paginate.prev=Précédent -default.paginate.next=Suivant +default.doesnt.match.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne correspond pas au pattern [{3}] +default.invalid.url.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une URL valide +default.invalid.creditCard.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas un numéro de carte de crédit valide +default.invalid.email.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas une adresse e-mail valide +default.invalid.range.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas contenue dans l'intervalle [{3}] à [{4}] +default.invalid.max.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.max.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est supérieure à la valeur maximum [{3}] +default.invalid.min.size.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] est inférieure à la valeur minimum [{3}] +default.invalid.validator.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] n'est pas valide +default.not.inlist.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne fait pas partie de la liste [{3}] +default.blank.message=La propriété [{0}] de la classe [{1}] ne peut pas être vide +default.not.equal.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] ne peut pas être égale à [{3}] +default.null.message=La propriété [{0}] de la classe [{1}] ne peut pas être nulle +default.not.unique.message=La propriété [{0}] de la classe [{1}] avec la valeur [{2}] doit être unique + +default.paginate.prev=Précédent +default.paginate.next=Suivant diff --git a/grails-app/i18n/messages_it.properties b/grails-app/i18n/messages_it.properties index 462ec1c..a90f1c7 100644 --- a/grails-app/i18n/messages_it.properties +++ b/grails-app/i18n/messages_it.properties @@ -1,55 +1,55 @@ -default.doesnt.match.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non corrisponde al pattern [{3}] -default.invalid.url.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un URL valido -default.invalid.creditCard.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un numero di carta di credito valido -default.invalid.email.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un indirizzo email valido -default.invalid.range.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo valido da [{3}] a [{4}] -default.invalid.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo di dimensioni valide da [{3}] a [{4}] -default.invalid.max.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] -default.invalid.min.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] -default.invalid.max.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] -default.invalid.min.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] -default.invalid.validator.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è valida -default.not.inlist.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è contenuta nella lista [{3}] -default.blank.message=La proprietà [{0}] della classe [{1}] non può essere vuota -default.not.equal.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non può essere uguale a [{3}] -default.null.message=La proprietà [{0}] della classe [{1}] non può essere null -default.not.unique.message=La proprietà [{0}] della classe [{1}] con valore [{2}] deve essere unica - -default.paginate.prev=Precedente -default.paginate.next=Successivo -default.boolean.true=Vero -default.boolean.false=Falso -default.date.format=dd/MM/yyyy HH:mm:ss z -default.number.format=0 - -default.created.message={0} {1} creato -default.updated.message={0} {1} aggiornato -default.deleted.message={0} {1} eliminato -default.not.deleted.message={0} {1} non può essere eliminato -default.not.found.message={0} non trovato con id {1} -default.optimistic.locking.failure=Un altro utente ha aggiornato questo {0} mentre si era in modifica - -default.home.label=Home -default.list.label={0} Elenco -default.add.label=Aggiungi {0} -default.new.label=Nuovo {0} -default.create.label=Crea {0} -default.show.label=Mostra {0} -default.edit.label=Modifica {0} - -default.button.create.label=Crea -default.button.edit.label=Modifica -default.button.update.label=Aggiorna -default.button.delete.label=Elimina -default.button.delete.confirm.message=Si è sicuri? - -# Data binding errors. Usa "typeMismatch.$className.$propertyName per la personalizzazione (es typeMismatch.Book.author) -typeMismatch.java.net.URL=La proprietà {0} deve essere un URL valido -typeMismatch.java.net.URI=La proprietà {0} deve essere un URI valido -typeMismatch.java.util.Date=La proprietà {0} deve essere una data valida -typeMismatch.java.lang.Double=La proprietà {0} deve essere un numero valido -typeMismatch.java.lang.Integer=La proprietà {0} deve essere un numero valido -typeMismatch.java.lang.Long=La proprietà {0} deve essere un numero valido -typeMismatch.java.lang.Short=La proprietà {0} deve essere un numero valido -typeMismatch.java.math.BigDecimal=La proprietà {0} deve essere un numero valido -typeMismatch.java.math.BigInteger=La proprietà {0} deve essere un numero valido +default.doesnt.match.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non corrisponde al pattern [{3}] +default.invalid.url.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un URL valido +default.invalid.creditCard.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un numero di carta di credito valido +default.invalid.email.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è un indirizzo email valido +default.invalid.range.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo valido da [{3}] a [{4}] +default.invalid.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non rientra nell'intervallo di dimensioni valide da [{3}] a [{4}] +default.invalid.max.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.max.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è maggiore di [{3}] +default.invalid.min.size.message=La proprietà [{0}] della classe [{1}] con valore [{2}] è minore di [{3}] +default.invalid.validator.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è valida +default.not.inlist.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non è contenuta nella lista [{3}] +default.blank.message=La proprietà [{0}] della classe [{1}] non può essere vuota +default.not.equal.message=La proprietà [{0}] della classe [{1}] con valore [{2}] non può essere uguale a [{3}] +default.null.message=La proprietà [{0}] della classe [{1}] non può essere null +default.not.unique.message=La proprietà [{0}] della classe [{1}] con valore [{2}] deve essere unica + +default.paginate.prev=Precedente +default.paginate.next=Successivo +default.boolean.true=Vero +default.boolean.false=Falso +default.date.format=dd/MM/yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} creato +default.updated.message={0} {1} aggiornato +default.deleted.message={0} {1} eliminato +default.not.deleted.message={0} {1} non può essere eliminato +default.not.found.message={0} non trovato con id {1} +default.optimistic.locking.failure=Un altro utente ha aggiornato questo {0} mentre si era in modifica + +default.home.label=Home +default.list.label={0} Elenco +default.add.label=Aggiungi {0} +default.new.label=Nuovo {0} +default.create.label=Crea {0} +default.show.label=Mostra {0} +default.edit.label=Modifica {0} + +default.button.create.label=Crea +default.button.edit.label=Modifica +default.button.update.label=Aggiorna +default.button.delete.label=Elimina +default.button.delete.confirm.message=Si è sicuri? + +# Data binding errors. Usa "typeMismatch.$className.$propertyName per la personalizzazione (es typeMismatch.Book.author) +typeMismatch.java.net.URL=La proprietà {0} deve essere un URL valido +typeMismatch.java.net.URI=La proprietà {0} deve essere un URI valido +typeMismatch.java.util.Date=La proprietà {0} deve essere una data valida +typeMismatch.java.lang.Double=La proprietà {0} deve essere un numero valido +typeMismatch.java.lang.Integer=La proprietà {0} deve essere un numero valido +typeMismatch.java.lang.Long=La proprietà {0} deve essere un numero valido +typeMismatch.java.lang.Short=La proprietà {0} deve essere un numero valido +typeMismatch.java.math.BigDecimal=La proprietà {0} deve essere un numero valido +typeMismatch.java.math.BigInteger=La proprietà {0} deve essere un numero valido diff --git a/grails-app/i18n/messages_ja.properties b/grails-app/i18n/messages_ja.properties index b5e4d18..d9e9b78 100644 --- a/grails-app/i18n/messages_ja.properties +++ b/grails-app/i18n/messages_ja.properties @@ -1,55 +1,55 @@ -default.doesnt.match.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]パターンと一致していません。 -default.invalid.url.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なURLではありません。 -default.invalid.creditCard.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なクレジットカード番号ではありません。 -default.invalid.email.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なメールアドレスではありません。 -default.invalid.range.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]範囲内を指定してください。 -default.invalid.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]以内を指定してください。 -default.invalid.max.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 -default.invalid.min.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 -default.invalid.max.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 -default.invalid.min.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 -default.invalid.validator.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、カスタムバリデーションを通過できません。 -default.not.inlist.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]リスト内に存在しません。 -default.blank.message=[{1}]クラスのプロパティ[{0}]の空白は許可されません。 -default.not.equal.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]と同等ではありません。 -default.null.message=[{1}]クラスのプロパティ[{0}]にnullは許可されません。 -default.not.unique.message=クラス[{1}]プロパティ[{0}]の値[{2}]は既に使用されています。 - -default.paginate.prev=戻る -default.paginate.next=次へ -default.boolean.true=はい -default.boolean.false=いいえ -default.date.format=yyyy/MM/dd HH:mm:ss z -default.number.format=0 - -default.created.message={0}(id:{1})を作成しました。 -default.updated.message={0}(id:{1})を更新しました。 -default.deleted.message={0}(id:{1})を削除しました。 -default.not.deleted.message={0}(id:{1})は削除できませんでした。 -default.not.found.message={0}(id:{1})は見つかりませんでした。 -default.optimistic.locking.failure=この{0}は編集中に他のユーザによって先に更新されています。 - -default.home.label=ホーム -default.list.label={0}リスト -default.add.label={0}を追加 -default.new.label={0}を新規作成 -default.create.label={0}を作成 -default.show.label={0}詳細 -default.edit.label={0}を編集 - -default.button.create.label=作成 -default.button.edit.label=編集 -default.button.update.label=更新 -default.button.delete.label=削除 -default.button.delete.confirm.message=本当に削除してよろしいですか? - -# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) -typeMismatch.java.net.URL={0}は有効なURLでなければなりません。 -typeMismatch.java.net.URI={0}は有効なURIでなければなりません。 -typeMismatch.java.util.Date={0}は有効な日付でなければなりません。 -typeMismatch.java.lang.Double={0}は有効な数値でなければなりません。 -typeMismatch.java.lang.Integer={0}は有効な数値でなければなりません。 -typeMismatch.java.lang.Long={0}は有効な数値でなければなりません。 -typeMismatch.java.lang.Short={0}は有効な数値でなければなりません。 -typeMismatch.java.math.BigDecimal={0}は有効な数値でなければなりません。 -typeMismatch.java.math.BigInteger={0}は有効な数値でなければなりません。 +default.doesnt.match.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]パターンと一致していません。 +default.invalid.url.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なURLではありません。 +default.invalid.creditCard.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なクレジットカード番号ではありません。 +default.invalid.email.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、有効なメールアドレスではありません。 +default.invalid.range.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]範囲内を指定してください。 +default.invalid.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]から[{4}]以内を指定してください。 +default.invalid.max.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.max.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最大値[{3}]より大きいです。 +default.invalid.min.size.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、最小値[{3}]より小さいです。 +default.invalid.validator.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、カスタムバリデーションを通過できません。 +default.not.inlist.message=クラス[{1}]プロパティ[{0}]の値[{2}]は、[{3}]リスト内に存在しません。 +default.blank.message=[{1}]クラスのプロパティ[{0}]の空白は許可されません。 +default.not.equal.message=クラス[{1}]プロパティ[{0}]の値[{2}]に[{3}]は許可されません。 +default.null.message=[{1}]クラスのプロパティ[{0}]にnullは許可されません。 +default.not.unique.message=クラス[{1}]プロパティ[{0}]の値[{2}]は既に使用されています。 + +default.paginate.prev=戻る +default.paginate.next=次へ +default.boolean.true=はい +default.boolean.false=いいえ +default.date.format=yyyy/MM/dd HH:mm:ss z +default.number.format=0 + +default.created.message={0}(id:{1})を作成しました。 +default.updated.message={0}(id:{1})を更新しました。 +default.deleted.message={0}(id:{1})を削除しました。 +default.not.deleted.message={0}(id:{1})は削除できませんでした。 +default.not.found.message={0}(id:{1})は見つかりませんでした。 +default.optimistic.locking.failure=この{0}は編集中に他のユーザによって先に更新されています。 + +default.home.label=ホーム +default.list.label={0}リスト +default.add.label={0}を追加 +default.new.label={0}を新規作成 +default.create.label={0}を作成 +default.show.label={0}詳細 +default.edit.label={0}を編集 + +default.button.create.label=作成 +default.button.edit.label=編集 +default.button.update.label=更新 +default.button.delete.label=削除 +default.button.delete.confirm.message=本当に削除してよろしいですか? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL={0}は有効なURLでなければなりません。 +typeMismatch.java.net.URI={0}は有効なURIでなければなりません。 +typeMismatch.java.util.Date={0}は有効な日付でなければなりません。 +typeMismatch.java.lang.Double={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Integer={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Long={0}は有効な数値でなければなりません。 +typeMismatch.java.lang.Short={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigDecimal={0}は有効な数値でなければなりません。 +typeMismatch.java.math.BigInteger={0}は有効な数値でなければなりません。 diff --git a/grails-app/i18n/messages_pt_BR.properties b/grails-app/i18n/messages_pt_BR.properties index 0c368f2..b5044e2 100644 --- a/grails-app/i18n/messages_pt_BR.properties +++ b/grails-app/i18n/messages_pt_BR.properties @@ -8,7 +8,7 @@ default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2 default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está entre a faixa de valores válida de [{3}] até [{4}] default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está na faixa de tamanho válida de [{3}] até [{4}] -default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapass o valor máximo [{3}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}] default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] @@ -16,7 +16,7 @@ default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2} default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um valor dentre os permitidos na lista [{3}] default.blank.message=O campo [{0}] da classe [{1}] não pode ficar em branco default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] -default.null.message=O campo [{0}] da classe [{1}] não pode ser vazia +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único default.paginate.prev=Anterior @@ -30,7 +30,7 @@ default.created.message={0} {1} criado default.updated.message={0} {1} atualizado default.deleted.message={0} {1} removido default.not.deleted.message={0} {1} não pode ser removido -default.not.found.message={0} não foi encontrado com id {1} +default.not.found.message={0} não foi encontrado com o id {1} default.optimistic.locking.failure=Outro usuário atualizou este [{0}] enquanto você tentou salvá-lo default.home.label=Principal @@ -56,4 +56,4 @@ typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. typeMismatch.java.lang.Long=O campo {0} deve ser um número válido. typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. -typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. \ No newline at end of file +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. diff --git a/grails-app/i18n/messages_pt_PT.properties b/grails-app/i18n/messages_pt_PT.properties index 43a6416..a386070 100644 --- a/grails-app/i18n/messages_pt_PT.properties +++ b/grails-app/i18n/messages_pt_PT.properties @@ -1,34 +1,34 @@ -# -# translation by miguel.ping@gmail.com, based on pt_BR translation by Lucas Teixeira - lucastex@gmail.com -# - -default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não corresponde ao padrão definido [{3}] -default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um URL válido -default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito -default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. -default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está dentro dos limites de valores válidos de [{3}] a [{4}] -default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] está fora dos limites de tamanho válido de [{3}] a [{4}] -default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}] -default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] -default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] -default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] -default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação -default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não se encontra nos valores permitidos da lista [{3}] -default.blank.message=O campo [{0}] da classe [{1}] não pode ser vazio -default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] -default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio -default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único - -default.paginate.prev=Anterior -default.paginate.next=Próximo - -# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para personalizar(eg typeMismatch.Book.author) -typeMismatch.java.net.URL=O campo {0} deve ser um URL válido. -typeMismatch.java.net.URI=O campo {0} deve ser um URI válido. -typeMismatch.java.util.Date=O campo {0} deve ser uma data válida -typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. -typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. -typeMismatch.java.lang.Long=O campo {0} deve ser um número valido. -typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. -typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. -typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. +# +# translation by miguel.ping@gmail.com, based on pt_BR translation by Lucas Teixeira - lucastex@gmail.com +# + +default.doesnt.match.message=O campo [{0}] da classe [{1}] com o valor [{2}] não corresponde ao padrão definido [{3}] +default.invalid.url.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um URL válido +default.invalid.creditCard.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um número válido de cartão de crédito +default.invalid.email.message=O campo [{0}] da classe [{1}] com o valor [{2}] não é um endereço de email válido. +default.invalid.range.message=O campo [{0}] da classe [{1}] com o valor [{2}] não está dentro dos limites de valores válidos de [{3}] a [{4}] +default.invalid.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] está fora dos limites de tamanho válido de [{3}] a [{4}] +default.invalid.max.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o valor máximo [{3}] +default.invalid.min.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o valor mínimo [{3}] +default.invalid.max.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] ultrapassa o tamanho máximo de [{3}] +default.invalid.min.size.message=O campo [{0}] da classe [{1}] com o valor [{2}] não atinge o tamanho mínimo de [{3}] +default.invalid.validator.message=O campo [{0}] da classe [{1}] com o valor [{2}] não passou na validação +default.not.inlist.message=O campo [{0}] da classe [{1}] com o valor [{2}] não se encontra nos valores permitidos da lista [{3}] +default.blank.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.equal.message=O campo [{0}] da classe [{1}] com o valor [{2}] não pode ser igual a [{3}] +default.null.message=O campo [{0}] da classe [{1}] não pode ser vazio +default.not.unique.message=O campo [{0}] da classe [{1}] com o valor [{2}] deve ser único + +default.paginate.prev=Anterior +default.paginate.next=Próximo + +# Mensagens de erro em atribuição de valores. Use "typeMismatch.$className.$propertyName" para personalizar(eg typeMismatch.Book.author) +typeMismatch.java.net.URL=O campo {0} deve ser um URL válido. +typeMismatch.java.net.URI=O campo {0} deve ser um URI válido. +typeMismatch.java.util.Date=O campo {0} deve ser uma data válida +typeMismatch.java.lang.Double=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Integer=O campo {0} deve ser um número válido. +typeMismatch.java.lang.Long=O campo {0} deve ser um número valido. +typeMismatch.java.lang.Short=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigDecimal=O campo {0} deve ser um número válido. +typeMismatch.java.math.BigInteger=O campo {0} deve ser um número válido. diff --git a/grails-app/i18n/messages_ru.properties b/grails-app/i18n/messages_ru.properties index 02239db..53a4bdc 100644 --- a/grails-app/i18n/messages_ru.properties +++ b/grails-app/i18n/messages_ru.properties @@ -1,31 +1,31 @@ -default.doesnt.match.message=Значение [{2}] поля [{0}] класса [{1}] не соответствует образцу [{3}] -default.invalid.url.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым URL-адресом -default.invalid.creditCard.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым номером кредитной карты -default.invalid.email.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым e-mail адресом -default.invalid.range.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в допустимый интервал от [{3}] до [{4}] -default.invalid.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) не попадает в допустимый интервал от [{3}] до [{4}] -default.invalid.max.message=Значение [{2}] поля [{0}] класса [{1}] больше чем максимально допустимое значение [{3}] -default.invalid.min.message=Значение [{2}] поля [{0}] класса [{1}] меньше чем минимально допустимое значение [{3}] -default.invalid.max.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) больше чем максимально допустимый размер [{3}] -default.invalid.min.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) меньше чем минимально допустимый размер [{3}] -default.invalid.validator.message=Значение [{2}] поля [{0}] класса [{1}] не допустимо -default.not.inlist.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в список допустимых значений [{3}] -default.blank.message=Поле [{0}] класса [{1}] не может быть пустым -default.not.equal.message=Значение [{2}] поля [{0}] класса [{1}] не может быть равно [{3}] -default.null.message=Поле [{0}] класса [{1}] не может иметь значение null -default.not.unique.message=Значение [{2}] поля [{0}] класса [{1}] должно быть уникальным - -default.paginate.prev=Предыдушая страница -default.paginate.next=Следующая страница - -# Ошибки при присвоении данных. Для точной настройки для полей классов используйте -# формат "typeMismatch.$className.$propertyName" (например, typeMismatch.Book.author) -typeMismatch.java.net.URL=Значение поля {0} не является допустимым URL -typeMismatch.java.net.URI=Значение поля {0} не является допустимым URI -typeMismatch.java.util.Date=Значение поля {0} не является допустимой датой -typeMismatch.java.lang.Double=Значение поля {0} не является допустимым числом -typeMismatch.java.lang.Integer=Значение поля {0} не является допустимым числом -typeMismatch.java.lang.Long=Значение поля {0} не является допустимым числом -typeMismatch.java.lang.Short=Значение поля {0} не является допустимым числом -typeMismatch.java.math.BigDecimal=Значение поля {0} не является допустимым числом -typeMismatch.java.math.BigInteger=Значение поля {0} не является допустимым числом +default.doesnt.match.message=Значение [{2}] поля [{0}] класса [{1}] не соответствует образцу [{3}] +default.invalid.url.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым URL-адресом +default.invalid.creditCard.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым номером кредитной карты +default.invalid.email.message=Значение [{2}] поля [{0}] класса [{1}] не является допустимым e-mail адресом +default.invalid.range.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) не попадает в допустимый интервал от [{3}] до [{4}] +default.invalid.max.message=Значение [{2}] поля [{0}] класса [{1}] больше чем максимально допустимое значение [{3}] +default.invalid.min.message=Значение [{2}] поля [{0}] класса [{1}] меньше чем минимально допустимое значение [{3}] +default.invalid.max.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) больше чем максимально допустимый размер [{3}] +default.invalid.min.size.message=Размер поля [{0}] класса [{1}] (значение: [{2}]) меньше чем минимально допустимый размер [{3}] +default.invalid.validator.message=Значение [{2}] поля [{0}] класса [{1}] не допустимо +default.not.inlist.message=Значение [{2}] поля [{0}] класса [{1}] не попадает в список допустимых значений [{3}] +default.blank.message=Поле [{0}] класса [{1}] не может быть пустым +default.not.equal.message=Значение [{2}] поля [{0}] класса [{1}] не может быть равно [{3}] +default.null.message=Поле [{0}] класса [{1}] не может иметь значение null +default.not.unique.message=Значение [{2}] поля [{0}] класса [{1}] должно быть уникальным + +default.paginate.prev=Предыдушая страница +default.paginate.next=Следующая страница + +# Ошибки при присвоении данных. Для точной настройки для полей классов используйте +# формат "typeMismatch.$className.$propertyName" (например, typeMismatch.Book.author) +typeMismatch.java.net.URL=Значение поля {0} не является допустимым URL +typeMismatch.java.net.URI=Значение поля {0} не является допустимым URI +typeMismatch.java.util.Date=Значение поля {0} не является допустимой датой +typeMismatch.java.lang.Double=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Integer=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Long=Значение поля {0} не является допустимым числом +typeMismatch.java.lang.Short=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigDecimal=Значение поля {0} не является допустимым числом +typeMismatch.java.math.BigInteger=Значение поля {0} не является допустимым числом diff --git a/grails-app/i18n/messages_sk.properties b/grails-app/i18n/messages_sk.properties new file mode 100644 index 0000000..73ee0dc --- /dev/null +++ b/grails-app/i18n/messages_sk.properties @@ -0,0 +1,56 @@ +default.doesnt.match.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nezodpovedá požadovanému formátu [{3}] +default.invalid.url.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je platná URL adresa +default.invalid.creditCard.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je platné číslo kreditnej karty +default.invalid.email.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je platná emailová adresa +default.invalid.range.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je v povolenom rozmedzí od [{3}] do [{4}] +default.invalid.size.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je v povolenom rozmedzí od [{3}] do [{4}] +default.invalid.max.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] prekračuje maximálnu povolenú hodnotu [{3}] +default.invalid.min.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] je menšia ako minimálna povolená hodnota [{3}] +default.invalid.max.size.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] prekračuje maximálnu veľkosť [{3}] +default.invalid.min.size.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] je menšia ako minimálna veľkosť [{3}] +default.invalid.validator.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] neprešla validáciou +default.not.inlist.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nie je obsiahnutá v zozname [{3}] +default.blank.message=Položka [{0}] triedy [{1}] nemôže byť prázdna +default.not.equal.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] nemôže byť rovnaká ako [{3}] +default.null.message=Položka [{0}] triedy [{1}] nemôže byť prázdna +default.not.unique.message=Položka [{0}] triedy [{1}] s hodnotou [{2}] musí byť unikátna + +default.paginate.prev=Predchádzajúce +default.paginate.next=Nasledujúce +default.boolean.true=Pravda +default.boolean.false=Nepravda +default.date.format=dd. MM. yyyy HH:mm:ss z +default.number.format=0 + +default.created.message={0} {1} vytvorené +default.updated.message={0} {1} aktualizované +default.deleted.message={0} {1} vymazané +default.not.deleted.message={0} {1} nemožno zmazať +default.not.found.message={0} nenájdené s id {1} +default.optimistic.locking.failure=Iný používateľ aktualizoval záznam {0}, práve keď bol vami editovaný + +default.home.label=Domov +default.list.label={0} Zoznam +default.add.label=Pridať {0} +default.new.label=Nový {0} +default.create.label=Vytvoriť {0} +default.show.label=Ukázať {0} +default.edit.label=Editovať {0} + +default.button.create.label=Vytvor +default.button.edit.label=Edituj +default.button.update.label=Aktualizuj +default.button.delete.label=Zmaž +default.button.delete.confirm.message=Ste si istý? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=Položka {0} musí byť platná URL adresa +typeMismatch.java.net.URI=Položka {0} musí byť platná URI adresa +typeMismatch.java.util.Date=Položka {0} musí byť platný dátum +typeMismatch.java.lang.Double=Položka {0} musí byť desatinné číslo +typeMismatch.java.lang.Integer=Položka {0} musí byť celé číslo +typeMismatch.java.lang.Long=Položka {0} musí byť celé číslo +typeMismatch.java.lang.Short=Položka {0} musí byť celé číslo +typeMismatch.java.math.BigDecimal=Položka {0} musí byť desatinné číslo +typeMismatch.java.math.BigInteger=Položka {0} musí byť celé číslo +typeMismatch=Položka {0} má nezhodný typ diff --git a/grails-app/i18n/messages_th.properties b/grails-app/i18n/messages_th.properties index 4f4076d..fd0dbb6 100644 --- a/grails-app/i18n/messages_th.properties +++ b/grails-app/i18n/messages_th.properties @@ -1,55 +1,55 @@ -default.doesnt.match.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบที่กำหนดไว้ใน [{3}] -default.invalid.url.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบ URL -default.invalid.creditCard.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบหมายเลขบัตรเครดิต -default.invalid.email.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบอีเมล์ -default.invalid.range.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีค่าที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] -default.invalid.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีขนาดที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] -default.invalid.max.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าเกิดกว่าค่ามากสุด [{3}] -default.invalid.min.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าน้อยกว่าค่าต่ำสุด [{3}] -default.invalid.max.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดเกินกว่าขนาดมากสุดของ [{3}] -default.invalid.min.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดต่ำกว่าขนาดต่ำสุดของ [{3}] -default.invalid.validator.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ผ่านการทวนสอบค่าที่ตั้งขึ้น -default.not.inlist.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้อยู่ในรายการต่อไปนี้ [{3}] -default.blank.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็นค่าว่างได้ -default.not.equal.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่สามารถเท่ากับ [{3}] ได้ -default.null.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็น null ได้ -default.not.unique.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] จะต้องไม่ซ้ำ (unique) - -default.paginate.prev=ก่อนหน้า -default.paginate.next=ถัดไป -default.boolean.true=จริง -default.boolean.false=เท็จ -default.date.format=dd-MM-yyyy HH:mm:ss z -default.number.format=0 - -default.created.message=สร้าง {0} {1} เรียบร้อยแล้ว -default.updated.message=ปรับปรุง {0} {1} เรียบร้อยแล้ว -default.deleted.message=ลบ {0} {1} เรียบร้อยแล้ว -default.not.deleted.message=ไม่สามารถลบ {0} {1} -default.not.found.message=ไม่พบ {0} ด้วย id {1} นี้ -default.optimistic.locking.failure=มีผู้ใช้ท่านอื่นปรับปรุง {0} ขณะที่คุณกำลังแก้ไขข้อมูลอยู่ - -default.home.label=หน้าแรก -default.list.label=รายการ {0} -default.add.label=เพิ่ม {0} -default.new.label=สร้าง {0} ใหม่ -default.create.label=สร้าง {0} -default.show.label=แสดง {0} -default.edit.label=แก้ไข {0} - -default.button.create.label=สร้าง -default.button.edit.label=แก้ไข -default.button.update.label=ปรับปรุง -default.button.delete.label=ลบ -default.button.delete.confirm.message=คุณแน่ใจหรือไม่ ? - -# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) -typeMismatch.java.net.URL=คุณสมบัติ '{0}' จะต้องเป็นค่า URL ที่ถูกต้อง -typeMismatch.java.net.URI=คุณสมบัติ '{0}' จะต้องเป็นค่า URI ที่ถูกต้อง -typeMismatch.java.util.Date=คุณสมบัติ '{0}' จะต้องมีค่าเป็นวันที่ -typeMismatch.java.lang.Double=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Double -typeMismatch.java.lang.Integer=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Integer -typeMismatch.java.lang.Long=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Long -typeMismatch.java.lang.Short=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Short -typeMismatch.java.math.BigDecimal=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigDecimal -typeMismatch.java.math.BigInteger=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigInteger +default.doesnt.match.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบที่กำหนดไว้ใน [{3}] +default.invalid.url.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบ URL +default.invalid.creditCard.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบหมายเลขบัตรเครดิต +default.invalid.email.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ถูกต้องตามรูปแบบอีเมล์ +default.invalid.range.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีค่าที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้มีขนาดที่ถูกต้องในช่วงจาก [{3}] ถึง [{4}] +default.invalid.max.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าเกิดกว่าค่ามากสุด [{3}] +default.invalid.min.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีค่าน้อยกว่าค่าต่ำสุด [{3}] +default.invalid.max.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดเกินกว่าขนาดมากสุดของ [{3}] +default.invalid.min.size.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] มีขนาดต่ำกว่าขนาดต่ำสุดของ [{3}] +default.invalid.validator.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ผ่านการทวนสอบค่าที่ตั้งขึ้น +default.not.inlist.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่ได้อยู่ในรายการต่อไปนี้ [{3}] +default.blank.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็นค่าว่างได้ +default.not.equal.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] ไม่สามารถเท่ากับ [{3}] ได้ +default.null.message=คุณสมบัติ [{0}] ของคลาส [{1}] ไม่สามารถเป็น null ได้ +default.not.unique.message=คุณสมบัติ [{0}] ของคลาส [{1}] ซึ่งมีค่าเป็น [{2}] จะต้องไม่ซ้ำ (unique) + +default.paginate.prev=ก่อนหน้า +default.paginate.next=ถัดไป +default.boolean.true=จริง +default.boolean.false=เท็จ +default.date.format=dd-MM-yyyy HH:mm:ss z +default.number.format=0 + +default.created.message=สร้าง {0} {1} เรียบร้อยแล้ว +default.updated.message=ปรับปรุง {0} {1} เรียบร้อยแล้ว +default.deleted.message=ลบ {0} {1} เรียบร้อยแล้ว +default.not.deleted.message=ไม่สามารถลบ {0} {1} +default.not.found.message=ไม่พบ {0} ด้วย id {1} นี้ +default.optimistic.locking.failure=มีผู้ใช้ท่านอื่นปรับปรุง {0} ขณะที่คุณกำลังแก้ไขข้อมูลอยู่ + +default.home.label=หน้าแรก +default.list.label=รายการ {0} +default.add.label=เพิ่ม {0} +default.new.label=สร้าง {0} ใหม่ +default.create.label=สร้าง {0} +default.show.label=แสดง {0} +default.edit.label=แก้ไข {0} + +default.button.create.label=สร้าง +default.button.edit.label=แก้ไข +default.button.update.label=ปรับปรุง +default.button.delete.label=ลบ +default.button.delete.confirm.message=คุณแน่ใจหรือไม่ ? + +# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author) +typeMismatch.java.net.URL=คุณสมบัติ '{0}' จะต้องเป็นค่า URL ที่ถูกต้อง +typeMismatch.java.net.URI=คุณสมบัติ '{0}' จะต้องเป็นค่า URI ที่ถูกต้อง +typeMismatch.java.util.Date=คุณสมบัติ '{0}' จะต้องมีค่าเป็นวันที่ +typeMismatch.java.lang.Double=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Double +typeMismatch.java.lang.Integer=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Integer +typeMismatch.java.lang.Long=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Long +typeMismatch.java.lang.Short=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท Short +typeMismatch.java.math.BigDecimal=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigDecimal +typeMismatch.java.math.BigInteger=คุณสมบัติ '{0}' จะต้องมีค่าเป็นจำนวนประเภท BigInteger diff --git a/grails-app/i18n/messages_zh_CN.properties b/grails-app/i18n/messages_zh_CN.properties index 782580b..b89bc93 100644 --- a/grails-app/i18n/messages_zh_CN.properties +++ b/grails-app/i18n/messages_zh_CN.properties @@ -1,18 +1,18 @@ -default.blank.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A -default.doesnt.match.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E\u5B9A\u4E49\u7684\u6A21\u5F0F [{3}]\u4E0D\u5339\u914D -default.invalid.creditCard.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7 -default.invalid.email.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740 -default.invalid.max.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 -default.invalid.max.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 -default.invalid.min.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F -default.invalid.min.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F -default.invalid.range.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) -default.invalid.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) -default.invalid.url.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684URL -default.invalid.validator.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u672A\u80FD\u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u9A8C\u8BC1 -default.not.equal.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E[{3}]\u4E0D\u76F8\u7B49 -default.not.inlist.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5217\u8868\u7684\u53D6\u503C\u8303\u56F4\u5185 -default.not.unique.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u5FC5\u987B\u662F\u552F\u4E00\u7684 -default.null.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3Anull -default.paginate.next=\u4E0B\u9875 -default.paginate.prev=\u4E0A\u9875 +default.blank.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3A\u7A7A +default.doesnt.match.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E\u5B9A\u4E49\u7684\u6A21\u5F0F [{3}]\u4E0D\u5339\u914D +default.invalid.creditCard.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684\u4FE1\u7528\u5361\u53F7 +default.invalid.email.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684\u7535\u5B50\u90AE\u4EF6\u5730\u5740 +default.invalid.max.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.max.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5927\u503C [{3}]\u8FD8\u5927 +default.invalid.min.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.min.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u6BD4\u6700\u5C0F\u503C [{3}]\u8FD8\u5C0F +default.invalid.range.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.size.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u7684\u5927\u5C0F\u4E0D\u5728\u5408\u6CD5\u7684\u8303\u56F4\u5185( [{3}] \uFF5E [{4}] ) +default.invalid.url.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u662F\u4E00\u4E2A\u5408\u6CD5\u7684URL +default.invalid.validator.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u672A\u80FD\u901A\u8FC7\u81EA\u5B9A\u4E49\u7684\u9A8C\u8BC1 +default.not.equal.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0E[{3}]\u4E0D\u76F8\u7B49 +default.not.inlist.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u4E0D\u5728\u5217\u8868\u7684\u53D6\u503C\u8303\u56F4\u5185 +default.not.unique.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u7684\u503C[{2}]\u5FC5\u987B\u662F\u552F\u4E00\u7684 +default.null.message=[{1}]\u7C7B\u7684\u5C5E\u6027[{0}]\u4E0D\u80FD\u4E3Anull +default.paginate.next=\u4E0B\u9875 +default.paginate.prev=\u4E0A\u9875 diff --git a/grails-app/init/specimenbrowser/Application.groovy b/grails-app/init/specimenbrowser/Application.groovy new file mode 100644 index 0000000..5c45de4 --- /dev/null +++ b/grails-app/init/specimenbrowser/Application.groovy @@ -0,0 +1,13 @@ +package specimenbrowser + +import grails.boot.GrailsApp +import grails.boot.config.GrailsAutoConfiguration + +import groovy.transform.CompileStatic + +@CompileStatic +class Application extends GrailsAutoConfiguration { + static void main(String[] args) { + GrailsApp.run(Application, args) + } +} \ No newline at end of file diff --git a/grails-app/conf/BootStrap.groovy b/grails-app/init/specimenbrowser/BootStrap.groovy similarity index 77% rename from grails-app/conf/BootStrap.groovy rename to grails-app/init/specimenbrowser/BootStrap.groovy index 1287dae..4f53207 100644 --- a/grails-app/conf/BootStrap.groovy +++ b/grails-app/init/specimenbrowser/BootStrap.groovy @@ -1,3 +1,5 @@ +package specimenbrowser + class BootStrap { def init = { servletContext -> diff --git a/grails-app/services/au/org/ala/specimenbrowser/ResourceService.groovy b/grails-app/services/au/org/ala/specimenbrowser/ResourceService.groovy new file mode 100644 index 0000000..661ae33 --- /dev/null +++ b/grails-app/services/au/org/ala/specimenbrowser/ResourceService.groovy @@ -0,0 +1,60 @@ +package au.org.ala.specimenbrowser + +import grails.config.Config +import grails.core.support.GrailsConfigurationAware +import groovy.json.JsonSlurper + +class ResourceService implements GrailsConfigurationAware { + /** The location of the resource configuration file */ + URL resourceConfigurationUrl + /** The location of the collectory web services */ + URL collectoryServicesUrl + /** The mappsings from collectory UIDs to resource types, eg co -> collection, dr -> dataResource */ + List resourceMappings + /** The list of resource metadata for each resource that is displayed */ + List resources + + /** + * Collect the resource information + */ + def buildResources() { + resources = [] + def js = new JsonSlurper() + def collectionsToRender = js.parse(resourceConfigurationUrl) + collectionsToRender.each { collection -> + def path = resourcePath(collection.uid) + def metadataUrl = new URL(collectoryServicesUrl, path + "/" + collection.uid) + try { + def collectionMetadata = js.parse(metadataUrl) + collectionMetadata.put("displayCollectionImage", collection.imageUrl) + this.resources << collectionMetadata + } catch (Exception ex) { + log.error("Unable to access while building collections " + metadataUrl, ex) + } + } + } + + + /** + * Get the path to the resource in the collectory, based on the resource UID prefix + * + * @param uid The resource UID (eg. co12, dr1456) + * @return The path to that resource (eg collection, dataResource) + */ + String resourcePath(String uid) { + def mapping = resourceMappings.find { m -> uid.startsWith(m.prefix) } + if (mapping) { + return mapping.path + } + throw new IllegalArgumentException("Unable to find collectory path for " + uid) + } + + @Override + void setConfiguration(Config config) { + resourceConfigurationUrl = new URL(config.getRequiredProperty("specimenbrowser.data.url")) + collectoryServicesUrl = new URL(config.getRequiredProperty("collectory.servicesUrl")) + resourceMappings = config.getRequiredProperty("collectory.resourceMapping", List) + buildResources() + } + +} diff --git a/grails-app/views/admin/counts.gsp b/grails-app/views/admin/counts.gsp index d5a92ce..0d7e639 100644 --- a/grails-app/views/admin/counts.gsp +++ b/grails-app/views/admin/counts.gsp @@ -2,25 +2,33 @@ - - Settings - Admin - Specimen image browser - Atlas of Living Australia - - - var biocacheServicesUrl = "${grailsApplication.config.biocacheServicesUrl}", - collectoryServicesURL = "${grailsApplication.config.collectory.servicesURL}", + + + Image Counts - Specimen image browser - Atlas of Living Australia + + + var biocacheServicesUrl = "${grailsApplication.config.biocache.servicesUrl}", + collectoryServicesURL = "${grailsApplication.config.collectory.servicesUrl}", browseUrl = "${createLink(controller: 'browse')}"; - + - - Image counts - + +
+
+
+ + + @@ -30,21 +38,15 @@
Resource UID Resource Number of images
- + + + + + \ No newline at end of file diff --git a/grails-app/views/admin/index.gsp b/grails-app/views/admin/index.gsp index 826bad3..7abd5f2 100644 --- a/grails-app/views/admin/index.gsp +++ b/grails-app/views/admin/index.gsp @@ -1,12 +1,27 @@ - + + Admin - Specimen image browser - Atlas of Living Australia - - + + + + + + + +
+
+
    +
  • Counts
  • +
  • Reload Resources
  • +
  • Application Administration
  • +
+
+
diff --git a/grails-app/views/admin/settings.gsp b/grails-app/views/admin/settings.gsp deleted file mode 100644 index e153b15..0000000 --- a/grails-app/views/admin/settings.gsp +++ /dev/null @@ -1,48 +0,0 @@ -<%@ page import="org.apache.commons.lang.StringEscapeUtils" %> - - - - - Settings - Admin - Specimen image browser - Atlas of Living Australia - - - - - Settings - - - - - - - - - - - - - - - %{----}% - - - - -
SettingValueComment
- ${setting.key} - - ${setting.value} - - ${setting.comment} - - - - -
- - \ No newline at end of file diff --git a/grails-app/views/admin/tools.gsp b/grails-app/views/admin/tools.gsp deleted file mode 100644 index 2d7c1ac..0000000 --- a/grails-app/views/admin/tools.gsp +++ /dev/null @@ -1,81 +0,0 @@ -<%@ page import="org.apache.commons.lang.StringEscapeUtils" %> - - - - - Tools - Admin - Specimen image browser - Atlas of Living Australia - - - - - Tools - - - - - - - - - - - - - -
ToolDescription
- - - Reads any defined config files and merges new config with old. Usually used after a change is - made to external config files. Note that this cannot remove a config item as the result is a - union of the old and new config. -
- - \ No newline at end of file diff --git a/grails-app/views/browse/index.gsp b/grails-app/views/browse/index.gsp index c02fa13..dba1450 100644 --- a/grails-app/views/browse/index.gsp +++ b/grails-app/views/browse/index.gsp @@ -2,32 +2,26 @@ + Specimens | Atlas of Living Australia - - - var biocacheServicesUrl = "${grailsApplication.config.biocacheServicesUrl}", + + + + var biocacheServicesUrl = "${grailsApplication.config.biocache.servicesUrl}", biocacheWebappUrl = "${grailsApplication.config.biocache.baseURL}", - collectoryServicesURL = "${grailsApplication.config.collectory.servicesURL}", + collectoryServicesURL = "${grailsApplication.config.collectory.servicesUrl}", collectoryURL = "${grailsApplication.config.collectory.baseURL}", imageViewerBaseUrl = "${createLink(controller: 'view', action: 'view')}", entityUid = "${uid}"; - + - - - -
+
- + var wsBase = "/occurrences/search.json", uiBase = "/occurrences/search", @@ -750,6 +744,6 @@ var imageLayout = new ImageLayout(); - + diff --git a/grails-app/views/index.gsp b/grails-app/views/index.gsp index 0cad5f7..f5f4f7e 100644 --- a/grails-app/views/index.gsp +++ b/grails-app/views/index.gsp @@ -1,8 +1,8 @@ - - Specimens | Atlas of Living Australia + + Specimens | ${grailsApplication.config.skin.orgNameLong} diff --git a/grails-app/views/index.gsp.new b/grails-app/views/index.gsp.new deleted file mode 100644 index f1f76a0..0000000 --- a/grails-app/views/index.gsp.new +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - ALA Web Theme - Home - - -%{----}% -
- -
-

Welcome to Grails

-

Congratulations, you have successfully started your first Grails application! At the moment - this is the default page, feel free to modify it to either redirect to a controller or display whatever - content you may choose. Below is a list of controllers that are currently deployed in this application, - click on each to execute its default action:

- - -
-
- - - - diff --git a/grails-app/views/layouts/adminLayout.gsp b/grails-app/views/layouts/adminLayout.gsp deleted file mode 100644 index 02f8c1b..0000000 --- a/grails-app/views/layouts/adminLayout.gsp +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - -
- - - - - - -
HomeAdministration
-
- -
-
- -
- -
- -
-
- ${flash.errorMessage} -
-
-
- - -
-
- ${flash.message} -
-
-
- - - -
-
-
- -
\ No newline at end of file diff --git a/grails-app/views/layouts/main.gsp b/grails-app/views/layouts/main.gsp deleted file mode 100644 index 166305a..0000000 --- a/grails-app/views/layouts/main.gsp +++ /dev/null @@ -1,104 +0,0 @@ -<%@ page import="org.codehaus.groovy.grails.commons.ConfigurationHolder" %> - - - - - - - - - - - - <g:layoutTitle /> - -<%-- Do not include JS & CSS files here - add them to your app's "application" module (in "Configuration/ApplicationResources.groovy") --%> - - - - // initialise plugins - jQuery(function(){ - // autocomplete on navbar search input - jQuery("form#search-form-2011 input#search-2011, form#search-inpage input#search, input#search-2013").autocomplete('https://bie.ala.org.au/search/auto.jsonp', { - extraParams: {limit: 100}, - dataType: 'jsonp', - parse: function(data) { - var rows = new Array(); - data = data.autoCompleteList; - for(var i=0; i - - - - - - - - -
- -
- -
- <%-- Borrowed from http://marcusasplund.com/optout/ --%> - Desktop version -
- - - - - - var pageTracker = _gat._getTracker("UA-4355440-1"); - pageTracker._initData(); - pageTracker._trackPageview(); - - // show warning if using IE6 - if ($.browser && $.browser.msie && $.browser.version.slice(0,1) == '6') { - $('#header').prepend($('
WARNING: This page is not compatible with IE6.' + - ' Many functions will still work but layout and image transparency will be disrupted.
')); - } -
- - - - - - diff --git a/grails-app/views/layouts/main.gsp.new b/grails-app/views/layouts/main.gsp.new deleted file mode 100644 index 0d83760..0000000 --- a/grails-app/views/layouts/main.gsp.new +++ /dev/null @@ -1,106 +0,0 @@ -<%@ page import="org.codehaus.groovy.grails.commons.ConfigurationHolder" %> - - - - - - - - - - - <g:layoutTitle /> - - <%-- Do not include JS & CSS files here - add them to your app's "application" module (in "Configuration/ApplicationResources.groovy") --%> - - - - // initialise plugins - jQuery(function(){ - // autocomplete on navbar search input - jQuery("form#search-form-2011 input#search-2011, form#search-inpage input#search, input#search-2013").autocomplete('http://bie.ala.org.au/search/auto.jsonp', { - extraParams: {limit: 100}, - dataType: 'jsonp', - parse: function(data) { - var rows = new Array(); - data = data.autoCompleteList; - for(var i=0; i - - - - - - - - - - -
- -
- -
- <%-- Borrowed from http://marcusasplund.com/optout/ --%> - Desktop version - %{-- Desktop version--}% -
- - - - - - var pageTracker = _gat._getTracker("UA-4355440-1"); - pageTracker._initData(); - pageTracker._trackPageview(); - - // show warning if using IE6 - if ($.browser.msie && $.browser.version.slice(0,1) == '6') { - $('#header').prepend($('
WARNING: This page is not compatible with IE6.' + - ' Many functions will still work but layout and image transparency will be disrupted.
')); - } -
- - - - - - \ No newline at end of file diff --git a/grails-app/views/notFound.gsp b/grails-app/views/notFound.gsp new file mode 100644 index 0000000..4c873ba --- /dev/null +++ b/grails-app/views/notFound.gsp @@ -0,0 +1,14 @@ + + + + Page Not Found + + + + +
    +
  • Error: Page Not Found (404)
  • +
  • Path: ${request.forwardURI}
  • +
+ + diff --git a/grails-app/views/view/homePage.gsp b/grails-app/views/view/homePage.gsp index 9927ab2..2108e96 100644 --- a/grails-app/views/view/homePage.gsp +++ b/grails-app/views/view/homePage.gsp @@ -1,35 +1,37 @@ - - - Images of specimens | Atlas of Living Australia - - -
-

Images of specimens from Australia’s Natural History Collections

-

- Images from Australia's Natural History collections made available by the museums and herbaria of Australia.
- To view images from all collections, click here.

-

- - - -
- -
- -
-

${collection.name}

-

${collection.institution.name}

- - - -

- -

-
- -
- - + + + Images of specimens | Atlas of Living Australia + + + + + +
+
+
+

${collection.name}

+

${collection.institution.name}

+ + + +

+ +

+
+
+
+ + diff --git a/grails-app/views/view/viewer.gsp b/grails-app/views/view/viewer.gsp index 164b625..e5ede66 100644 --- a/grails-app/views/view/viewer.gsp +++ b/grails-app/views/view/viewer.gsp @@ -2,6 +2,13 @@ + + + + + + + Image viewer | ${params.recordId} | Specimens | Atlas of Living Australia - - - + + + + + + + + + + + + @@ -32,6 +48,5 @@
- \ No newline at end of file diff --git a/grails-release-plugin-bug-workaround_pom.xml b/grails-release-plugin-bug-workaround_pom.xml deleted file mode 100644 index 92fb0d7..0000000 --- a/grails-release-plugin-bug-workaround_pom.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - 4.0.0 - au.org.ala - SET_ARTIFACT_ID - war - SET_VERSION_STRING - SET_NAME - - - diff --git a/grails-wrapper.jar b/grails-wrapper.jar new file mode 100644 index 0000000..b9bd249 Binary files /dev/null and b/grails-wrapper.jar differ diff --git a/grailsw b/grailsw new file mode 100755 index 0000000..8d0cc12 --- /dev/null +++ b/grailsw @@ -0,0 +1,152 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Grails start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRAILS_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" "-XX:CICompilerCount=3"' + + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +JAR_PATH=$APP_HOME/grails-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" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + JAVACMD=`cygpath --unix "$JAVACMD"` + JAR_PATH=`cygpath --path --mixed "$JAR_PATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRAILS_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRAILS_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRAILS_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRAILS_OPTS + +exec "$JAVACMD" -jar "${JVM_OPTS[@]}" "$JAR_PATH" "$@" diff --git a/grailsw.bat b/grailsw.bat new file mode 100755 index 0000000..14734e4 --- /dev/null +++ b/grailsw.bat @@ -0,0 +1,89 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Grails startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRAILS_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1" "-XX:CICompilerCount=3" + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +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 init + +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 + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line +set JAR_PATH=%APP_HOME%/grails-wrapper.jar + +@rem Execute Grails +"%JAVA_EXE%" -jar %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRAILS_OPTS% %JAR_PATH% %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRAILS_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRAILS_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..d002523 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'specimenbrowser' + diff --git a/src/integration-test/resources/GebConfig.groovy b/src/integration-test/resources/GebConfig.groovy new file mode 100644 index 0000000..0d97e35 --- /dev/null +++ b/src/integration-test/resources/GebConfig.groovy @@ -0,0 +1,25 @@ +import org.openqa.selenium.chrome.ChromeDriver +import org.openqa.selenium.chrome.ChromeOptions +import org.openqa.selenium.firefox.FirefoxDriver + +environments { + + // run via “./gradlew -Dgeb.env=chrome iT” + chrome { + driver = { new ChromeDriver() } + } + + // run via “./gradlew -Dgeb.env=chromeHeadless iT” + chromeHeadless { + driver = { + ChromeOptions o = new ChromeOptions() + o.addArguments('headless') + new ChromeDriver(o) + } + } + + // run via “./gradlew -Dgeb.env=firefox iT” + firefox { + driver = { new FirefoxDriver() } + } +} diff --git a/test/unit/au/org/ala/specimenbrowser/AdminControllerTests.groovy b/test/unit/au/org/ala/specimenbrowser/AdminControllerTests.groovy deleted file mode 100644 index dcd7b59..0000000 --- a/test/unit/au/org/ala/specimenbrowser/AdminControllerTests.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package au.org.ala.specimenbrowser - - - -import grails.test.mixin.* -import org.junit.* - -/** - * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions - */ -@TestFor(AdminController) -class AdminControllerTests { - - void testSomething() { - fail "Implement me" - } -} diff --git a/test/unit/au/org/ala/specimenbrowser/ViewControllerTests.groovy b/test/unit/au/org/ala/specimenbrowser/ViewControllerTests.groovy deleted file mode 100644 index b609ada..0000000 --- a/test/unit/au/org/ala/specimenbrowser/ViewControllerTests.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package au.org.ala.specimenbrowser - - - -import grails.test.mixin.* -import org.junit.* - -/** - * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions - */ -@TestFor(ViewController) -class ViewControllerTests { - - void testSomething() { - fail "Implement me" - } -} diff --git a/test/unit/specimenbrowser/BrowseControllerTests.groovy b/test/unit/specimenbrowser/BrowseControllerTests.groovy deleted file mode 100644 index 922a07e..0000000 --- a/test/unit/specimenbrowser/BrowseControllerTests.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package specimenbrowser - -import au.org.ala.specimenbrowser.BrowseController -import grails.test.mixin.* - -/** - * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions - */ -@TestFor(BrowseController) -class BrowseControllerTests { - - void testSomething() { - fail "Implement me" - } -} diff --git a/test/unit/specimenbrowser/SpecimenTagTagLibSpec.groovy b/test/unit/specimenbrowser/SpecimenTagTagLibSpec.groovy deleted file mode 100644 index 12b320f..0000000 --- a/test/unit/specimenbrowser/SpecimenTagTagLibSpec.groovy +++ /dev/null @@ -1,20 +0,0 @@ -package specimenbrowser - -import grails.test.mixin.TestFor -import spock.lang.Specification - -/** - * See the API for {@link grails.test.mixin.web.GroovyPageUnitTestMixin} for usage instructions - */ -@TestFor(SpecimenTagTagLib) -class SpecimenTagTagLibSpec extends Specification { - - def setup() { - } - - def cleanup() { - } - - void "test something"() { - } -} diff --git a/upgrade-notes.md b/upgrade-notes.md new file mode 100644 index 0000000..195d0d2 --- /dev/null +++ b/upgrade-notes.md @@ -0,0 +1,3 @@ +* Using wenjars version for knockout library. This is handled by an asset javascript that requires the path to the actual libraries +* images-client-plugin contains an internal leaflet.js library +* images-client-plugin requires the importing of xml-apis:xml-apis \ No newline at end of file diff --git a/web-app/WEB-INF/applicationContext.xml b/web-app/WEB-INF/applicationContext.xml deleted file mode 100644 index a48dec0..0000000 --- a/web-app/WEB-INF/applicationContext.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Grails application factory bean - - - - - - A bean that manages Grails plugins - - - - - - - - - - - - - - - - utf-8 - - - - - \ No newline at end of file diff --git a/web-app/WEB-INF/sitemesh.xml b/web-app/WEB-INF/sitemesh.xml deleted file mode 100644 index 72399ce..0000000 --- a/web-app/WEB-INF/sitemesh.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/web-app/WEB-INF/tld/c.tld b/web-app/WEB-INF/tld/c.tld deleted file mode 100644 index 5e18236..0000000 --- a/web-app/WEB-INF/tld/c.tld +++ /dev/null @@ -1,572 +0,0 @@ - - - - - JSTL 1.2 core library - JSTL core - 1.2 - c - http://java.sun.com/jsp/jstl/core - - - - Provides core validation features for JSTL tags. - - - org.apache.taglibs.standard.tlv.JstlCoreTLV - - - - - - Catches any Throwable that occurs in its body and optionally - exposes it. - - catch - org.apache.taglibs.standard.tag.common.core.CatchTag - JSP - - -Name of the exported scoped variable for the -exception thrown from a nested action. The type of the -scoped variable is the type of the exception thrown. - - var - false - false - - - - - - Simple conditional tag that establishes a context for - mutually exclusive conditional operations, marked by - <when> and <otherwise> - - choose - org.apache.taglibs.standard.tag.common.core.ChooseTag - JSP - - - - - Simple conditional tag, which evalutes its body if the - supplied condition is true and optionally exposes a Boolean - scripting variable representing the evaluation of this condition - - if - org.apache.taglibs.standard.tag.rt.core.IfTag - JSP - - -The test condition that determines whether or -not the body content should be processed. - - test - true - true - boolean - - - -Name of the exported scoped variable for the -resulting value of the test condition. The type -of the scoped variable is Boolean. - - var - false - false - - - -Scope for var. - - scope - false - false - - - - - - Retrieves an absolute or relative URL and exposes its contents - to either the page, a String in 'var', or a Reader in 'varReader'. - - import - org.apache.taglibs.standard.tag.rt.core.ImportTag - org.apache.taglibs.standard.tei.ImportTEI - JSP - - -The URL of the resource to import. - - url - true - true - - - -Name of the exported scoped variable for the -resource's content. The type of the scoped -variable is String. - - var - false - false - - - -Scope for var. - - scope - false - false - - - -Name of the exported scoped variable for the -resource's content. The type of the scoped -variable is Reader. - - varReader - false - false - - - -Name of the context when accessing a relative -URL resource that belongs to a foreign -context. - - context - false - true - - - -Character encoding of the content at the input -resource. - - charEncoding - false - true - - - - - - The basic iteration tag, accepting many different - collection types and supporting subsetting and other - functionality - - forEach - org.apache.taglibs.standard.tag.rt.core.ForEachTag - org.apache.taglibs.standard.tei.ForEachTEI - JSP - - -Collection of items to iterate over. - - items - false - true - java.lang.Object - - java.lang.Object - - - - -If items specified: -Iteration begins at the item located at the -specified index. First item of the collection has -index 0. -If items not specified: -Iteration begins with index set at the value -specified. - - begin - false - true - int - - - -If items specified: -Iteration ends at the item located at the -specified index (inclusive). -If items not specified: -Iteration ends when index reaches the value -specified. - - end - false - true - int - - - -Iteration will only process every step items of -the collection, starting with the first one. - - step - false - true - int - - - -Name of the exported scoped variable for the -current item of the iteration. This scoped -variable has nested visibility. Its type depends -on the object of the underlying collection. - - var - false - false - - - -Name of the exported scoped variable for the -status of the iteration. Object exported is of type -javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested -visibility. - - varStatus - false - false - - - - - - Iterates over tokens, separated by the supplied delimeters - - forTokens - org.apache.taglibs.standard.tag.rt.core.ForTokensTag - JSP - - -String of tokens to iterate over. - - items - true - true - java.lang.String - - java.lang.String - - - - -The set of delimiters (the characters that -separate the tokens in the string). - - delims - true - true - java.lang.String - - - -Iteration begins at the token located at the -specified index. First token has index 0. - - begin - false - true - int - - - -Iteration ends at the token located at the -specified index (inclusive). - - end - false - true - int - - - -Iteration will only process every step tokens -of the string, starting with the first one. - - step - false - true - int - - - -Name of the exported scoped variable for the -current item of the iteration. This scoped -variable has nested visibility. - - var - false - false - - - -Name of the exported scoped variable for the -status of the iteration. Object exported is of -type -javax.servlet.jsp.jstl.core.LoopTag -Status. This scoped variable has nested -visibility. - - varStatus - false - false - - - - - - Like <%= ... >, but for expressions. - - out - org.apache.taglibs.standard.tag.rt.core.OutTag - JSP - - -Expression to be evaluated. - - value - true - true - - - -Default value if the resulting value is null. - - default - false - true - - - -Determines whether characters <,>,&,'," in the -resulting string should be converted to their -corresponding character entity codes. Default value is -true. - - escapeXml - false - true - - - - - - - Subtag of <choose> that follows <when> tags - and runs only if all of the prior conditions evaluated to - 'false' - - otherwise - org.apache.taglibs.standard.tag.common.core.OtherwiseTag - JSP - - - - - Adds a parameter to a containing 'import' tag's URL. - - param - org.apache.taglibs.standard.tag.rt.core.ParamTag - JSP - - -Name of the query string parameter. - - name - true - true - - - -Value of the parameter. - - value - false - true - - - - - - Redirects to a new URL. - - redirect - org.apache.taglibs.standard.tag.rt.core.RedirectTag - JSP - - -The URL of the resource to redirect to. - - url - false - true - - - -Name of the context when redirecting to a relative URL -resource that belongs to a foreign context. - - context - false - true - - - - - - Removes a scoped variable (from a particular scope, if specified). - - remove - org.apache.taglibs.standard.tag.common.core.RemoveTag - empty - - -Name of the scoped variable to be removed. - - var - true - false - - - -Scope for var. - - scope - false - false - - - - - - Sets the result of an expression evaluation in a 'scope' - - set - org.apache.taglibs.standard.tag.rt.core.SetTag - JSP - - -Name of the exported scoped variable to hold the value -specified in the action. The type of the scoped variable is -whatever type the value expression evaluates to. - - var - false - false - - - -Expression to be evaluated. - - value - false - true - - java.lang.Object - - - - -Target object whose property will be set. Must evaluate to -a JavaBeans object with setter property property, or to a -java.util.Map object. - - target - false - true - - - -Name of the property to be set in the target object. - - property - false - true - - - -Scope for var. - - scope - false - false - - - - - - Creates a URL with optional query parameters. - - url - org.apache.taglibs.standard.tag.rt.core.UrlTag - JSP - - -Name of the exported scoped variable for the -processed url. The type of the scoped variable is -String. - - var - false - false - - - -Scope for var. - - scope - false - false - - - -URL to be processed. - - value - false - true - - - -Name of the context when specifying a relative URL -resource that belongs to a foreign context. - - context - false - true - - - - - - Subtag of <choose> that includes its body if its - condition evalutes to 'true' - - when - org.apache.taglibs.standard.tag.rt.core.WhenTag - JSP - - -The test condition that determines whether or not the -body content should be processed. - - test - true - true - boolean - - - - diff --git a/web-app/WEB-INF/tld/fmt.tld b/web-app/WEB-INF/tld/fmt.tld deleted file mode 100644 index 2ae4776..0000000 --- a/web-app/WEB-INF/tld/fmt.tld +++ /dev/null @@ -1,671 +0,0 @@ - - - - - JSTL 1.2 i18n-capable formatting library - JSTL fmt - 1.2 - fmt - http://java.sun.com/jsp/jstl/fmt - - - - Provides core validation features for JSTL tags. - - - org.apache.taglibs.standard.tlv.JstlFmtTLV - - - - - - Sets the request character encoding - - requestEncoding - org.apache.taglibs.standard.tag.rt.fmt.RequestEncodingTag - empty - - -Name of character encoding to be applied when -decoding request parameters. - - value - false - true - - - - - - Stores the given locale in the locale configuration variable - - setLocale - org.apache.taglibs.standard.tag.rt.fmt.SetLocaleTag - empty - - -A String value is interpreted as the -printable representation of a locale, which -must contain a two-letter (lower-case) -language code (as defined by ISO-639), -and may contain a two-letter (upper-case) -country code (as defined by ISO-3166). -Language and country codes must be -separated by hyphen (-) or underscore -(_). - - value - true - true - - - -Vendor- or browser-specific variant. -See the java.util.Locale javadocs for -more information on variants. - - variant - false - true - - - -Scope of the locale configuration variable. - - scope - false - false - - - - - - Specifies the time zone for any time formatting or parsing actions - nested in its body - - timeZone - org.apache.taglibs.standard.tag.rt.fmt.TimeZoneTag - JSP - - -The time zone. A String value is interpreted as -a time zone ID. This may be one of the time zone -IDs supported by the Java platform (such as -"America/Los_Angeles") or a custom time zone -ID (such as "GMT-8"). See -java.util.TimeZone for more information on -supported time zone formats. - - value - true - true - - - - - - Stores the given time zone in the time zone configuration variable - - setTimeZone - org.apache.taglibs.standard.tag.rt.fmt.SetTimeZoneTag - empty - - -The time zone. A String value is interpreted as -a time zone ID. This may be one of the time zone -IDs supported by the Java platform (such as -"America/Los_Angeles") or a custom time zone -ID (such as "GMT-8"). See java.util.TimeZone for -more information on supported time zone -formats. - - value - true - true - - - -Name of the exported scoped variable which -stores the time zone of type -java.util.TimeZone. - - var - false - false - - - -Scope of var or the time zone configuration -variable. - - scope - false - false - - - - - - Loads a resource bundle to be used by its tag body - - bundle - org.apache.taglibs.standard.tag.rt.fmt.BundleTag - JSP - - -Resource bundle base name. This is the bundle's -fully-qualified resource name, which has the same -form as a fully-qualified class name, that is, it uses -"." as the package component separator and does not -have any file type (such as ".class" or ".properties") -suffix. - - basename - true - true - - - -Prefix to be prepended to the value of the message -key of any nested <fmt:message> action. - - prefix - false - true - - - - - - Loads a resource bundle and stores it in the named scoped variable or - the bundle configuration variable - - setBundle - org.apache.taglibs.standard.tag.rt.fmt.SetBundleTag - empty - - -Resource bundle base name. This is the bundle's -fully-qualified resource name, which has the same -form as a fully-qualified class name, that is, it uses -"." as the package component separator and does not -have any file type (such as ".class" or ".properties") -suffix. - - basename - true - true - - - -Name of the exported scoped variable which stores -the i18n localization context of type -javax.servlet.jsp.jstl.fmt.LocalizationC -ontext. - - var - false - false - - - -Scope of var or the localization context -configuration variable. - - scope - false - false - - - - - - Maps key to localized message and performs parametric replacement - - message - org.apache.taglibs.standard.tag.rt.fmt.MessageTag - JSP - - -Message key to be looked up. - - key - false - true - - - -Localization context in whose resource -bundle the message key is looked up. - - bundle - false - true - - - -Name of the exported scoped variable -which stores the localized message. - - var - false - false - - - -Scope of var. - - scope - false - false - - - - - - Supplies an argument for parametric replacement to a containing - <message> tag - - param - org.apache.taglibs.standard.tag.rt.fmt.ParamTag - JSP - - -Argument used for parametric replacement. - - value - false - true - - - - - - Formats a numeric value as a number, currency, or percentage - - formatNumber - org.apache.taglibs.standard.tag.rt.fmt.FormatNumberTag - JSP - - -Numeric value to be formatted. - - value - false - true - - - -Specifies whether the value is to be -formatted as number, currency, or -percentage. - - type - false - true - - - -Custom formatting pattern. - - pattern - false - true - - - -ISO 4217 currency code. Applied only -when formatting currencies (i.e. if type is -equal to "currency"); ignored otherwise. - - currencyCode - false - true - - - -Currency symbol. Applied only when -formatting currencies (i.e. if type is equal -to "currency"); ignored otherwise. - - currencySymbol - false - true - - - -Specifies whether the formatted output -will contain any grouping separators. - - groupingUsed - false - true - - - -Maximum number of digits in the integer -portion of the formatted output. - - maxIntegerDigits - false - true - - - -Minimum number of digits in the integer -portion of the formatted output. - - minIntegerDigits - false - true - - - -Maximum number of digits in the -fractional portion of the formatted output. - - maxFractionDigits - false - true - - - -Minimum number of digits in the -fractional portion of the formatted output. - - minFractionDigits - false - true - - - -Name of the exported scoped variable -which stores the formatted result as a -String. - - var - false - false - - - -Scope of var. - - scope - false - false - - - - - - Parses the string representation of a number, currency, or percentage - - parseNumber - org.apache.taglibs.standard.tag.rt.fmt.ParseNumberTag - JSP - - -String to be parsed. - - value - false - true - - - -Specifies whether the string in the value -attribute should be parsed as a number, -currency, or percentage. - - type - false - true - - - -Custom formatting pattern that determines -how the string in the value attribute is to be -parsed. - - pattern - false - true - - - -Locale whose default formatting pattern (for -numbers, currencies, or percentages, -respectively) is to be used during the parse -operation, or to which the pattern specified -via the pattern attribute (if present) is -applied. - - parseLocale - false - true - - - -Specifies whether just the integer portion of -the given value should be parsed. - - integerOnly - false - true - - - -Name of the exported scoped variable which -stores the parsed result (of type -java.lang.Number). - - var - false - false - - - -Scope of var. - - scope - false - false - - - - - - Formats a date and/or time using the supplied styles and pattern - - formatDate - org.apache.taglibs.standard.tag.rt.fmt.FormatDateTag - empty - - -Date and/or time to be formatted. - - value - true - true - - - -Specifies whether the time, the date, or both -the time and date components of the given -date are to be formatted. - - type - false - true - - - -Predefined formatting style for dates. Follows -the semantics defined in class -java.text.DateFormat. Applied only -when formatting a date or both a date and -time (i.e. if type is missing or is equal to -"date" or "both"); ignored otherwise. - - dateStyle - false - true - - - -Predefined formatting style for times. Follows -the semantics defined in class -java.text.DateFormat. Applied only -when formatting a time or both a date and -time (i.e. if type is equal to "time" or "both"); -ignored otherwise. - - timeStyle - false - true - - - -Custom formatting style for dates and times. - - pattern - false - true - - - -Time zone in which to represent the formatted -time. - - timeZone - false - true - - - -Name of the exported scoped variable which -stores the formatted result as a String. - - var - false - false - - - -Scope of var. - - scope - false - false - - - - - - Parses the string representation of a date and/or time - - parseDate - org.apache.taglibs.standard.tag.rt.fmt.ParseDateTag - JSP - - -Date string to be parsed. - - value - false - true - - - -Specifies whether the date string in the -value attribute is supposed to contain a -time, a date, or both. - - type - false - true - - - -Predefined formatting style for days -which determines how the date -component of the date string is to be -parsed. Applied only when formatting a -date or both a date and time (i.e. if type -is missing or is equal to "date" or "both"); -ignored otherwise. - - dateStyle - false - true - - - -Predefined formatting styles for times -which determines how the time -component in the date string is to be -parsed. Applied only when formatting a -time or both a date and time (i.e. if type -is equal to "time" or "both"); ignored -otherwise. - - timeStyle - false - true - - - -Custom formatting pattern which -determines how the date string is to be -parsed. - - pattern - false - true - - - -Time zone in which to interpret any time -information in the date string. - - timeZone - false - true - - - -Locale whose predefined formatting styles -for dates and times are to be used during -the parse operation, or to which the -pattern specified via the pattern -attribute (if present) is applied. - - parseLocale - false - true - - - -Name of the exported scoped variable in -which the parsing result (of type -java.util.Date) is stored. - - var - false - false - - - -Scope of var. - - scope - false - false - - - - diff --git a/web-app/WEB-INF/tld/grails.tld b/web-app/WEB-INF/tld/grails.tld deleted file mode 100644 index 9bd036b..0000000 --- a/web-app/WEB-INF/tld/grails.tld +++ /dev/null @@ -1,550 +0,0 @@ - - - The Grails custom tag library - 0.2 - grails - http://grails.codehaus.org/tags - - - link - org.codehaus.groovy.grails.web.taglib.jsp.JspLinkTag - JSP - - action - false - true - - - controller - false - true - - - id - false - true - - - url - false - true - - - params - false - true - - true - - - form - org.codehaus.groovy.grails.web.taglib.jsp.JspFormTag - JSP - - action - false - true - - - controller - false - true - - - id - false - true - - - url - false - true - - - method - true - true - - true - - - select - org.codehaus.groovy.grails.web.taglib.jsp.JspSelectTag - JSP - - name - true - true - - - value - false - true - - - optionKey - false - true - - - optionValue - false - true - - true - - - datePicker - org.codehaus.groovy.grails.web.taglib.jsp.JspDatePickerTag - empty - - name - true - true - - - value - false - true - - - precision - false - true - - false - - - currencySelect - org.codehaus.groovy.grails.web.taglib.jsp.JspCurrencySelectTag - empty - - name - true - true - - - value - false - true - - true - - - localeSelect - org.codehaus.groovy.grails.web.taglib.jsp.JspLocaleSelectTag - empty - - name - true - true - - - value - false - true - - true - - - timeZoneSelect - org.codehaus.groovy.grails.web.taglib.jsp.JspTimeZoneSelectTag - empty - - name - true - true - - - value - false - true - - true - - - checkBox - org.codehaus.groovy.grails.web.taglib.jsp.JspCheckboxTag - empty - - name - true - true - - - value - true - true - - true - - - hasErrors - org.codehaus.groovy.grails.web.taglib.jsp.JspHasErrorsTag - JSP - - model - false - true - - - bean - false - true - - - field - false - true - - false - - - eachError - org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag - JSP - - model - false - true - - - bean - false - true - - - field - false - true - - false - - - renderErrors - org.codehaus.groovy.grails.web.taglib.jsp.JspEachErrorTag - JSP - - model - false - true - - - bean - false - true - - - field - false - true - - - as - true - true - - false - - - message - org.codehaus.groovy.grails.web.taglib.jsp.JspMessageTag - JSP - - code - false - true - - - error - false - true - - - default - false - true - - false - - - remoteFunction - org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteFunctionTag - empty - - before - false - true - - - after - false - true - - - action - false - true - - - controller - false - true - - - id - false - true - - - url - false - true - - - params - false - true - - - asynchronous - false - true - - - method - false - true - - - update - false - true - - - onSuccess - false - true - - - onFailure - false - true - - - onComplete - false - true - - - onLoading - false - true - - - onLoaded - false - true - - - onInteractive - false - true - - true - - - remoteLink - org.codehaus.groovy.grails.web.taglib.jsp.JspRemoteLinkTag - JSP - - before - false - true - - - after - false - true - - - action - false - true - - - controller - false - true - - - id - false - true - - - url - false - true - - - params - false - true - - - asynchronous - false - true - - - method - false - true - - - update - false - true - - - onSuccess - false - true - - - onFailure - false - true - - - onComplete - false - true - - - onLoading - false - true - - - onLoaded - false - true - - - onInteractive - false - true - - true - - - formRemote - org.codehaus.groovy.grails.web.taglib.jsp.JspFormRemoteTag - JSP - - before - false - true - - - after - false - true - - - action - false - true - - - controller - false - true - - - id - false - true - - - url - false - true - - - params - false - true - - - asynchronous - false - true - - - method - false - true - - - update - false - true - - - onSuccess - false - true - - - onFailure - false - true - - - onComplete - false - true - - - onLoading - false - true - - - onLoaded - false - true - - - onInteractive - false - true - - true - - - invokeTag - org.codehaus.groovy.grails.web.taglib.jsp.JspInvokeGrailsTagLibTag - JSP - - it - java.lang.Object - true - NESTED - - - tagName - true - true - - true - - - diff --git a/web-app/WEB-INF/tld/spring.tld b/web-app/WEB-INF/tld/spring.tld deleted file mode 100644 index a0a8c6f..0000000 --- a/web-app/WEB-INF/tld/spring.tld +++ /dev/null @@ -1,457 +0,0 @@ - - - - Spring Framework JSP Tag Library - 3.0 - spring - http://www.springframework.org/tags - - - - Sets default HTML escape value for the current page. - Overrides a "defaultHtmlEscape" context-param in web.xml, if any. - - htmlEscape - org.springframework.web.servlet.tags.HtmlEscapeTag - JSP - - Set the default value for HTML escaping, to be put - into the current PageContext. - defaultHtmlEscape - true - true - - - - - - Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - escapeBody - org.springframework.web.servlet.tags.EscapeBodyTag - JSP - - Set HTML escaping for this tag, as boolean value. Overrides the - default HTML escaping setting for the current page. - htmlEscape - false - true - - - Set JavaScript escaping for this tag, as boolean value. - Default is false. - javaScriptEscape - false - true - - - - - - Retrieves the message with the given code, or text if code isn't resolvable. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - message - org.springframework.web.servlet.tags.MessageTag - JSP - - A MessageSourceResolvable argument (direct or through JSP EL). - Fits nicely when used in conjunction with Spring's own validation error - classes which all implement the MessageSourceResolvable interface. For - example, this allows you to iterate over all of the errors in a form, - passing each error (using a runtime expression) as the value of this - 'message' attribute, thus effecting the easy display of such error - messages. - message - false - true - - - The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. - code - false - true - - - Set optional message arguments for this tag, as a - (comma-)delimited String (each String argument can contain JSP EL), - an Object array (used as argument array), or a single Object (used - as single argument). - arguments - false - true - - - The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). - argumentSeparator - false - true - - - Default text to output when a message for the given code - could not be found. If both text and code are not set, the tag will - output null. - text - false - true - - - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result - gets outputted to the writer (i.e. typically directly to the JSP). - var - false - true - - - The scope to use when exporting the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - scope - false - true - - - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - htmlEscape - false - true - - - Set JavaScript escaping for this tag, as boolean value. Default is false. - javaScriptEscape - false - true - - - - - - Retrieves the theme message with the given code, or text if code isn't resolvable. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - theme - org.springframework.web.servlet.tags.ThemeTag - JSP - - A MessageSourceResolvable argument (direct or through JSP EL). - message - false - true - - - The code (key) to use when looking up the message. - If code is not provided, the text attribute will be used. - code - false - true - - - Set optional message arguments for this tag, as a - (comma-)delimited String (each String argument can contain JSP EL), - an Object array (used as argument array), or a single Object (used - as single argument). - arguments - false - true - - - The separator character to be used for splitting the - arguments string value; defaults to a 'comma' (','). - argumentSeparator - false - true - - - Default text to output when a message for the given code - could not be found. If both text and code are not set, the tag will - output null. - text - false - true - - - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result - gets outputted to the writer (i.e. typically directly to the JSP). - var - false - true - - - The scope to use when exporting the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - scope - false - true - - - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - htmlEscape - false - true - - - Set JavaScript escaping for this tag, as boolean value. Default is false. - javaScriptEscape - false - true - - - - - - Provides Errors instance in case of bind errors. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - hasBindErrors - org.springframework.web.servlet.tags.BindErrorsTag - JSP - - errors - org.springframework.validation.Errors - - - The name of the bean in the request, that needs to be - inspected for errors. If errors are available for this bean, they - will be bound under the 'errors' key. - name - true - true - - - Set HTML escaping for this tag, as boolean value. - Overrides the default HTML escaping setting for the current page. - htmlEscape - false - true - - - - - - Sets a nested path to be used by the bind tag's path. - - nestedPath - org.springframework.web.servlet.tags.NestedPathTag - JSP - - nestedPath - java.lang.String - - - Set the path that this tag should apply. E.g. 'customer' - to allow bind paths like 'address.street' rather than - 'customer.address.street'. - path - true - true - - - - - - Provides BindStatus object for the given bind path. - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml). - - bind - org.springframework.web.servlet.tags.BindTag - JSP - - status - org.springframework.web.servlet.support.BindStatus - - - The path to the bean or bean property to bind status - information for. For instance account.name, company.address.zipCode - or just employee. The status object will exported to the page scope, - specifically for this bean or bean property - path - true - true - - - Set whether to ignore a nested path, if any. Default is to not ignore. - ignoreNestedPath - false - true - - - Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. - htmlEscape - false - true - - - - - - Provides transformation of variables to Strings, using an appropriate - custom PropertyEditor from BindTag (can only be used inside BindTag). - The HTML escaping flag participates in a page-wide or application-wide setting - (i.e. by HtmlEscapeTag or a 'defaultHtmlEscape' context-param in web.xml). - - transform - org.springframework.web.servlet.tags.TransformTag - JSP - - The value to transform. This is the actual object you want - to have transformed (for instance a Date). Using the PropertyEditor that - is currently in use by the 'spring:bind' tag. - value - true - true - - - The string to use when binding the result to the page, - request, session or application scope. If not specified, the result gets - outputted to the writer (i.e. typically directly to the JSP). - var - false - true - - - The scope to use when exported the result to a variable. - This attribute is only used when var is also set. Possible values are - page, request, session and application. - scope - false - true - - - Set HTML escaping for this tag, as boolean value. Overrides - the default HTML escaping setting for the current page. - htmlEscape - false - true - - - - - URL tag based on the JSTL c:url tag. This variant is fully - backwards compatible with the standard tag. Enhancements include support - for URL template parameters. - url - org.springframework.web.servlet.tags.UrlTag - JSP - - The URL to build. This value can include template place holders - that are replaced with the URL encoded value of the named parameter. Parameters - must be defined using the param tag inside the body of this tag. - value - true - true - - - Specifies a remote application context path. The default is the - current application context path. - context - false - true - - - The name of the variable to export the URL value to. - var - false - true - - - The scope for the var. 'application', 'session', 'request' and - 'page' scopes are supported. Defaults to page scope. This attribute has no - effect unless the var attribute is also defined. - scope - false - true - - - Set HTML escaping for this tag, as a boolean value. Overrides the - default HTML escaping setting for the current page. - htmlEscape - false - true - - - Set JavaScript escaping for this tag, as a boolean value. - Default is false. - javaScriptEscape - false - true - - - - - Parameter tag based on the JSTL c:param tag. The sole purpose is to - support params inside the spring:url tag. - param - org.springframework.web.servlet.tags.ParamTag - JSP - - The name of the parameter. - name - true - true - - - The value of the parameter. - value - false - true - - - - - Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable. - eval - org.springframework.web.servlet.tags.EvalTag - JSP - - The expression to evaluate. - expression - true - true - - - The name of the variable to export the evaluation result to. - var - false - true - - - The scope for the var. 'application', 'session', 'request' and - 'page' scopes are supported. Defaults to page scope. This attribute has no - effect unless the var attribute is also defined. - scope - false - true - - - Set HTML escaping for this tag, as a boolean value. Overrides the - default HTML escaping setting for the current page. - htmlEscape - false - true - - - Set JavaScript escaping for this tag, as a boolean value. Default is false. - javaScriptEscape - false - true - - - - diff --git a/web-app/css/errors.css b/web-app/css/errors.css deleted file mode 100644 index bdb58bc..0000000 --- a/web-app/css/errors.css +++ /dev/null @@ -1,109 +0,0 @@ -h1, h2 { - margin: 10px 25px 5px; -} - -h2 { - font-size: 1.1em; -} - -.filename { - font-style: italic; -} - -.exceptionMessage { - margin: 10px; - border: 1px solid #000; - padding: 5px; - background-color: #E9E9E9; -} - -.stack, -.snippet { - margin: 0 25px 10px; -} - -.stack, -.snippet { - border: 1px solid #ccc; - -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); - -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); - box-shadow: 0 0 2px rgba(0,0,0,0.2); -} - -/* error details */ -.error-details { - border-top: 1px solid #FFAAAA; - -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); - -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); - box-shadow: 0 0 2px rgba(0,0,0,0.2); - border-bottom: 1px solid #FFAAAA; - -mox-box-shadow: 0 0 2px rgba(0,0,0,0.2); - -webkit-box-shadow: 0 0 2px rgba(0,0,0,0.2); - box-shadow: 0 0 2px rgba(0,0,0,0.2); - background-color:#FFF3F3; - line-height: 1.5; - overflow: hidden; - padding: 5px; - padding-left:25px; -} - -.error-details dt { - clear: left; - float: left; - font-weight: bold; - margin-right: 5px; -} - -.error-details dt:after { - content: ":"; -} - -.error-details dd { - display: block; -} - -/* stack trace */ -.stack { - padding: 5px; - overflow: auto; - height: 150px; -} - -/* code snippet */ -.snippet { - background-color: #fff; - font-family: monospace; -} - -.snippet .line { - display: block; -} - -.snippet .lineNumber { - background-color: #ddd; - color: #999; - display: inline-block; - margin-right: 5px; - padding: 0 3px; - text-align: right; - width: 3em; -} - -.snippet .error { - background-color: #fff3f3; - font-weight: bold; -} - -.snippet .error .lineNumber { - background-color: #faa; - color: #333; - font-weight: bold; -} - -.snippet .line:first-child .lineNumber { - padding-top: 5px; -} - -.snippet .line:last-child .lineNumber { - padding-bottom: 5px; -} \ No newline at end of file diff --git a/web-app/css/main.css b/web-app/css/main.css deleted file mode 100644 index a55945d..0000000 --- a/web-app/css/main.css +++ /dev/null @@ -1,596 +0,0 @@ -/* FONT STACK */ -body, -input, select, textarea { - font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; -} - -h1, h2, h3, h4, h5, h6 { - line-height: 1.1; -} - -/* BASE LAYOUT */ - -html { - background-color: #ddd; - background-image: -moz-linear-gradient(center top, #aaa, #ddd); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #aaa), color-stop(1, #ddd)); - background-image: linear-gradient(top, #aaa, #ddd); - filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#aaaaaa', EndColorStr = '#dddddd'); - background-repeat: no-repeat; - height: 100%; - /* change the box model to exclude the padding from the calculation of 100% height (IE8+) */ - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -html.no-cssgradients { - background-color: #aaa; -} - -.ie6 html { - height: 100%; -} - -html * { - margin: 0; -} - -body { - background: #ffffff; - color: #333333; - margin: 0 auto; - max-width: 960px; - overflow-x: hidden; /* prevents box-shadow causing a horizontal scrollbar in firefox when viewport < 960px wide */ - -moz-box-shadow: 0 0 0.3em #255b17; - -webkit-box-shadow: 0 0 0.3em #255b17; - box-shadow: 0 0 0.3em #255b17; -} - -#grailsLogo { - background-color: #abbf78; -} - -/* replace with .no-boxshadow body if you have modernizr available */ -.ie6 body, -.ie7 body, -.ie8 body { - border-color: #255b17; - border-style: solid; - border-width: 0 1px; -} - -.ie6 body { - height: 100%; -} - -a:link, a:visited, a:hover { - color: #48802c; -} - -a:hover, a:active { - outline: none; /* prevents outline in webkit on active links but retains it for tab focus */ -} - -h1 { - color: #48802c; - font-weight: normal; - font-size: 1.25em; - margin: 0.8em 0 0.3em 0; -} - -ul { - padding: 0; -} - -img { - border: 0; -} - -/* GENERAL */ - -#grailsLogo a { - display: inline-block; - margin: 1em; -} - -.content { -} - -.content h1 { - border-bottom: 1px solid #CCCCCC; - margin: 0.8em 1em 0.3em; - padding: 0 0.25em; -} - -.scaffold-list h1 { - border: none; -} - -.footer { - background: #abbf78; - color: #000; - clear: both; - font-size: 0.8em; - margin-top: 1.5em; - padding: 1em; - min-height: 1em; -} - -.footer a { - color: #255b17; -} - -.spinner { - background: url(../images/spinner.gif) 50% 50% no-repeat transparent; - height: 16px; - width: 16px; - padding: 0.5em; - position: absolute; - right: 0; - top: 0; - text-indent: -9999px; -} - -/* NAVIGATION MENU */ - -.nav { - background-color: #efefef; - padding: 0.5em 0.75em; - -moz-box-shadow: 0 0 3px 1px #aaaaaa; - -webkit-box-shadow: 0 0 3px 1px #aaaaaa; - box-shadow: 0 0 3px 1px #aaaaaa; - zoom: 1; -} - -.nav ul { - overflow: hidden; - padding-left: 0; - zoom: 1; -} - -.nav li { - display: block; - float: left; - list-style-type: none; - margin-right: 0.5em; - padding: 0; -} - -.nav a { - color: #666666; - display: block; - padding: 0.25em 0.7em; - text-decoration: none; - -moz-border-radius: 0.3em; - -webkit-border-radius: 0.3em; - border-radius: 0.3em; -} - -.nav a:active, .nav a:visited { - color: #666666; -} - -.nav a:focus, .nav a:hover { - background-color: #999999; - color: #ffffff; - outline: none; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); -} - -.no-borderradius .nav a:focus, .no-borderradius .nav a:hover { - background-color: transparent; - color: #444444; - text-decoration: underline; -} - -.nav a.home, .nav a.list, .nav a.create { - background-position: 0.7em center; - background-repeat: no-repeat; - text-indent: 25px; -} - -.nav a.home { - background-image: url(../images/skin/house.png); -} - -.nav a.list { - background-image: url(../images/skin/database_table.png); -} - -.nav a.create { - background-image: url(../images/skin/database_add.png); -} - -/* CREATE/EDIT FORMS AND SHOW PAGES */ - -fieldset, -.property-list { - margin: 0.6em 1.25em 0 1.25em; - padding: 0.3em 1.8em 1.25em; - position: relative; - zoom: 1; - border: none; -} - -.property-list .fieldcontain { - list-style: none; - overflow: hidden; - zoom: 1; -} - -.fieldcontain { - margin-top: 1em; -} - -.fieldcontain label, -.fieldcontain .property-label { - color: #666666; - text-align: right; - width: 25%; -} - -.fieldcontain .property-label { - float: left; -} - -.fieldcontain .property-value { - display: block; - margin-left: 27%; -} - -label { - cursor: pointer; - display: inline-block; - margin: 0 0.25em 0 0; -} - -input, select, textarea { - background-color: #fcfcfc; - border: 1px solid #cccccc; - font-size: 1em; - padding: 0.2em 0.4em; -} - -select { - padding: 0.2em 0.2em 0.2em 0; -} - -select[multiple] { - vertical-align: top; -} - -textarea { - width: 250px; - height: 150px; - overflow: auto; /* IE always renders vertical scrollbar without this */ - vertical-align: top; -} - -input[type=checkbox], input[type=radio] { - background-color: transparent; - border: 0; - padding: 0; -} - -input:focus, select:focus, textarea:focus { - background-color: #ffffff; - border: 1px solid #eeeeee; - outline: 0; - -moz-box-shadow: 0 0 0.5em #ffffff; - -webkit-box-shadow: 0 0 0.5em #ffffff; - box-shadow: 0 0 0.5em #ffffff; -} - -.required-indicator { - color: #48802C; - display: inline-block; - font-weight: bold; - margin-left: 0.3em; - position: relative; - top: 0.1em; -} - -ul.one-to-many { - display: inline-block; - list-style-position: inside; - vertical-align: top; -} - -.ie6 ul.one-to-many, .ie7 ul.one-to-many { - display: inline; - zoom: 1; -} - -ul.one-to-many li.add { - list-style-type: none; -} - -/* EMBEDDED PROPERTIES */ - -fieldset.embedded { - background-color: transparent; - border: 1px solid #CCCCCC; - margin-left: 0; - margin-right: 0; - padding-left: 0; - padding-right: 0; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -fieldset.embedded legend { - margin: 0 1em; -} - -/* MESSAGES AND ERRORS */ - -.errors, -.message { - font-size: 0.8em; - line-height: 2; - margin: 1em 2em; - padding: 0.25em; -} - -.message { - background: #f3f3ff; - border: 1px solid #b2d1ff; - color: #006dba; - -moz-box-shadow: 0 0 0.25em #b2d1ff; - -webkit-box-shadow: 0 0 0.25em #b2d1ff; - box-shadow: 0 0 0.25em #b2d1ff; -} - -.errors { - background: #fff3f3; - border: 1px solid #ffaaaa; - color: #cc0000; - -moz-box-shadow: 0 0 0.25em #ff8888; - -webkit-box-shadow: 0 0 0.25em #ff8888; - box-shadow: 0 0 0.25em #ff8888; -} - -.errors ul, -.message { - padding: 0; -} - -.errors li { - list-style: none; - background: transparent url(../images/skin/exclamation.png) 0.5em 50% no-repeat; - text-indent: 2.2em; -} - -.message { - background: transparent url(../images/skin/information.png) 0.5em 50% no-repeat; - text-indent: 2.2em; -} - -/* form fields with errors */ - -.error input, .error select, .error textarea { - background: #fff3f3; - border-color: #ffaaaa; - color: #cc0000; -} - -.error input:focus, .error select:focus, .error textarea:focus { - -moz-box-shadow: 0 0 0.5em #ffaaaa; - -webkit-box-shadow: 0 0 0.5em #ffaaaa; - box-shadow: 0 0 0.5em #ffaaaa; -} - -/* same effects for browsers that support HTML5 client-side validation (these have to be specified separately or IE will ignore the entire rule) */ - -input:invalid, select:invalid, textarea:invalid { - background: #fff3f3; - border-color: #ffaaaa; - color: #cc0000; -} - -input:invalid:focus, select:invalid:focus, textarea:invalid:focus { - -moz-box-shadow: 0 0 0.5em #ffaaaa; - -webkit-box-shadow: 0 0 0.5em #ffaaaa; - box-shadow: 0 0 0.5em #ffaaaa; -} - -/* TABLES */ - -table { - border-top: 1px solid #DFDFDF; - border-collapse: collapse; - width: 100%; - margin-bottom: 1em; -} - -tr { - border: 0; -} - -tr>td:first-child, tr>th:first-child { - padding-left: 1.25em; -} - -tr>td:last-child, tr>th:last-child { - padding-right: 1.25em; -} - -td, th { - line-height: 1.5em; - padding: 0.5em 0.6em; - text-align: left; - vertical-align: top; -} - -th { - background-color: #efefef; - background-image: -moz-linear-gradient(top, #ffffff, #eaeaea); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(1, #eaeaea)); - filter: progid:DXImageTransform.Microsoft.gradient(startColorStr = '#ffffff', EndColorStr = '#eaeaea'); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#eaeaea')"; - color: #666666; - font-weight: bold; - line-height: 1.7em; - padding: 0.2em 0.6em; -} - -thead th { - white-space: nowrap; -} - -th a { - display: block; - text-decoration: none; -} - -th a:link, th a:visited { - color: #666666; -} - -th a:hover, th a:focus { - color: #333333; -} - -th.sortable a { - background-position: right; - background-repeat: no-repeat; - padding-right: 1.1em; -} - -th.asc a { - background-image: url(../images/skin/sorted_asc.gif); -} - -th.desc a { - background-image: url(../images/skin/sorted_desc.gif); -} - -.odd { - background: #f7f7f7; -} - -.even { - background: #ffffff; -} - -th:hover, tr:hover { - background: #E1F2B6; -} - -/* PAGINATION */ - -.pagination { - border-top: 0; - margin: 0; - padding: 0.3em 0.2em; - text-align: center; - -moz-box-shadow: 0 0 3px 1px #AAAAAA; - -webkit-box-shadow: 0 0 3px 1px #AAAAAA; - box-shadow: 0 0 3px 1px #AAAAAA; - background-color: #EFEFEF; -} - -.pagination a, -.pagination .currentStep { - color: #666666; - display: inline-block; - margin: 0 0.1em; - padding: 0.25em 0.7em; - text-decoration: none; - -moz-border-radius: 0.3em; - -webkit-border-radius: 0.3em; - border-radius: 0.3em; -} - -.pagination a:hover, .pagination a:focus, -.pagination .currentStep { - background-color: #999999; - color: #ffffff; - outline: none; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); -} - -.no-borderradius .pagination a:hover, .no-borderradius .pagination a:focus, -.no-borderradius .pagination .currentStep { - background-color: transparent; - color: #444444; - text-decoration: underline; -} - -/* ACTION BUTTONS */ - -.buttons { - background-color: #efefef; - overflow: hidden; - padding: 0.3em; - -moz-box-shadow: 0 0 3px 1px #aaaaaa; - -webkit-box-shadow: 0 0 3px 1px #aaaaaa; - box-shadow: 0 0 3px 1px #aaaaaa; - margin: 0.1em 0 0 0; - border: none; -} - -.buttons input, -.buttons a { - background-color: transparent; - border: 0; - color: #666666; - cursor: pointer; - display: inline-block; - margin: 0 0.25em 0; - overflow: visible; - padding: 0.25em 0.7em; - text-decoration: none; - - -moz-border-radius: 0.3em; - -webkit-border-radius: 0.3em; - border-radius: 0.3em; -} - -.buttons input:hover, .buttons input:focus, -.buttons a:hover, .buttons a:focus { - background-color: #999999; - color: #ffffff; - outline: none; - text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -.no-borderradius .buttons input:hover, .no-borderradius .buttons input:focus, -.no-borderradius .buttons a:hover, .no-borderradius .buttons a:focus { - background-color: transparent; - color: #444444; - text-decoration: underline; -} - -.buttons .delete, .buttons .edit, .buttons .save { - background-position: 0.7em center; - background-repeat: no-repeat; - text-indent: 25px; -} - -.ie6 .buttons input.delete, .ie6 .buttons input.edit, .ie6 .buttons input.save, -.ie7 .buttons input.delete, .ie7 .buttons input.edit, .ie7 .buttons input.save { - padding-left: 36px; -} - -.buttons .delete { - background-image: url(../images/skin/database_delete.png); -} - -.buttons .edit { - background-image: url(../images/skin/database_edit.png); -} - -.buttons .save { - background-image: url(../images/skin/database_save.png); -} - -a.skip { - position: absolute; - left: -9999px; -} diff --git a/web-app/css/mobile.css b/web-app/css/mobile.css deleted file mode 100644 index 167f502..0000000 --- a/web-app/css/mobile.css +++ /dev/null @@ -1,82 +0,0 @@ -/* Styles for mobile devices */ - -@media screen and (max-width: 480px) { - .nav { - padding: 0.5em; - } - - .nav li { - margin: 0 0.5em 0 0; - padding: 0.25em; - } - - /* Hide individual steps in pagination, just have next & previous */ - .pagination .step, .pagination .currentStep { - display: none; - } - - .pagination .prevLink { - float: left; - } - - .pagination .nextLink { - float: right; - } - - /* pagination needs to wrap around floated buttons */ - .pagination { - overflow: hidden; - } - - /* slightly smaller margin around content body */ - fieldset, - .property-list { - padding: 0.3em 1em 1em; - } - - input, textarea { - width: 100%; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - } - - select, input[type=checkbox], input[type=radio], input[type=submit], input[type=button], input[type=reset] { - width: auto; - } - - /* hide all but the first column of list tables */ - .scaffold-list td:not(:first-child), - .scaffold-list th:not(:first-child) { - display: none; - } - - .scaffold-list thead th { - text-align: center; - } - - /* stack form elements */ - .fieldcontain { - margin-top: 0.6em; - } - - .fieldcontain label, - .fieldcontain .property-label, - .fieldcontain .property-value { - display: block; - float: none; - margin: 0 0 0.25em 0; - text-align: left; - width: auto; - } - - .errors ul, - .message p { - margin: 0.5em; - } - - .error ul { - margin-left: 0; - } -} diff --git a/web-app/images/apple-touch-icon-retina.png b/web-app/images/apple-touch-icon-retina.png deleted file mode 100644 index 5cc83ed..0000000 Binary files a/web-app/images/apple-touch-icon-retina.png and /dev/null differ diff --git a/web-app/images/apple-touch-icon.png b/web-app/images/apple-touch-icon.png deleted file mode 100644 index aba337f..0000000 Binary files a/web-app/images/apple-touch-icon.png and /dev/null differ diff --git a/web-app/images/favicon.ico b/web-app/images/favicon.ico deleted file mode 100644 index 3dfcb92..0000000 Binary files a/web-app/images/favicon.ico and /dev/null differ diff --git a/web-app/images/grails_logo.jpg b/web-app/images/grails_logo.jpg deleted file mode 100644 index 8be657c..0000000 Binary files a/web-app/images/grails_logo.jpg and /dev/null differ diff --git a/web-app/images/grails_logo.png b/web-app/images/grails_logo.png deleted file mode 100644 index 9836b93..0000000 Binary files a/web-app/images/grails_logo.png and /dev/null differ diff --git a/web-app/images/leftnav_btm.png b/web-app/images/leftnav_btm.png deleted file mode 100644 index 582e1eb..0000000 Binary files a/web-app/images/leftnav_btm.png and /dev/null differ diff --git a/web-app/images/leftnav_midstretch.png b/web-app/images/leftnav_midstretch.png deleted file mode 100644 index 3cb8a51..0000000 Binary files a/web-app/images/leftnav_midstretch.png and /dev/null differ diff --git a/web-app/images/leftnav_top.png b/web-app/images/leftnav_top.png deleted file mode 100644 index 6afec7d..0000000 Binary files a/web-app/images/leftnav_top.png and /dev/null differ diff --git a/web-app/images/skin/database_add.png b/web-app/images/skin/database_add.png deleted file mode 100644 index 802bd6c..0000000 Binary files a/web-app/images/skin/database_add.png and /dev/null differ diff --git a/web-app/images/skin/database_delete.png b/web-app/images/skin/database_delete.png deleted file mode 100644 index cce652e..0000000 Binary files a/web-app/images/skin/database_delete.png and /dev/null differ diff --git a/web-app/images/skin/database_edit.png b/web-app/images/skin/database_edit.png deleted file mode 100644 index e501b66..0000000 Binary files a/web-app/images/skin/database_edit.png and /dev/null differ diff --git a/web-app/images/skin/database_save.png b/web-app/images/skin/database_save.png deleted file mode 100644 index 44c06dd..0000000 Binary files a/web-app/images/skin/database_save.png and /dev/null differ diff --git a/web-app/images/skin/database_table.png b/web-app/images/skin/database_table.png deleted file mode 100644 index 693709c..0000000 Binary files a/web-app/images/skin/database_table.png and /dev/null differ diff --git a/web-app/images/skin/exclamation.png b/web-app/images/skin/exclamation.png deleted file mode 100644 index c37bd06..0000000 Binary files a/web-app/images/skin/exclamation.png and /dev/null differ diff --git a/web-app/images/skin/house.png b/web-app/images/skin/house.png deleted file mode 100644 index fed6221..0000000 Binary files a/web-app/images/skin/house.png and /dev/null differ diff --git a/web-app/images/skin/information.png b/web-app/images/skin/information.png deleted file mode 100644 index 12cd1ae..0000000 Binary files a/web-app/images/skin/information.png and /dev/null differ diff --git a/web-app/images/skin/shadow.jpg b/web-app/images/skin/shadow.jpg deleted file mode 100644 index b7ed44f..0000000 Binary files a/web-app/images/skin/shadow.jpg and /dev/null differ diff --git a/web-app/images/skin/sorted_asc.gif b/web-app/images/skin/sorted_asc.gif deleted file mode 100644 index 6b179c1..0000000 Binary files a/web-app/images/skin/sorted_asc.gif and /dev/null differ diff --git a/web-app/images/skin/sorted_desc.gif b/web-app/images/skin/sorted_desc.gif deleted file mode 100644 index 38b3a01..0000000 Binary files a/web-app/images/skin/sorted_desc.gif and /dev/null differ diff --git a/web-app/images/spinner.gif b/web-app/images/spinner.gif deleted file mode 100644 index 1ed786f..0000000 Binary files a/web-app/images/spinner.gif and /dev/null differ diff --git a/web-app/images/springsource.png b/web-app/images/springsource.png deleted file mode 100644 index e806d00..0000000 Binary files a/web-app/images/springsource.png and /dev/null differ diff --git a/web-app/js/knockout-3.0.0.js b/web-app/js/knockout-3.0.0.js deleted file mode 100644 index 1c6945a..0000000 --- a/web-app/js/knockout-3.0.0.js +++ /dev/null @@ -1,94 +0,0 @@ -// Knockout JavaScript library v3.0.0 -// (c) Steven Sanderson - http://knockoutjs.com/ -// License: MIT (http://www.opensource.org/licenses/mit-license.php) - -(function() {(function(q){var y=this||(0,eval)("this"),w=y.document,K=y.navigator,u=y.jQuery,B=y.JSON;(function(q){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?q(module.exports||exports):"function"===typeof define&&define.amd?define(["exports"],q):q(y.ko={})})(function(F){function G(a,c){return null===a||typeof a in N?a===c:!1}function H(b,c,d,e){a.d[b]={init:function(b){a.a.f.set(b,L,{});return{controlsDescendantBindings:!0}},update:function(b,h,k,m,f){k=a.a.f.get(b,L);h=a.a.c(h()); -m=!d!==!h;var p=!k.ob;if(p||c||m!==k.Db)p&&(k.ob=a.a.Ya(a.e.childNodes(b),!0)),m?(p||a.e.S(b,a.a.Ya(k.ob)),a.Ta(e?e(f,h):f,b)):a.e.Z(b),k.Db=m}};a.g.Y[b]=!1;a.e.P[b]=!0}var a="undefined"!==typeof F?F:{};a.b=function(b,c){for(var d=b.split("."),e=a,g=0;ga.a.l(c,b[f])&&c.push(b[f]);return c},ha:function(a,b){a=a||[];for(var f=[],c=0,d=a.length;cd?f&&b.push(c):f||b.splice(d,1)},extend:function(a,b){if(b)for(var f in b)b.hasOwnProperty(f)&& -(a[f]=b[f]);return a},K:b,Da:function(a,b){if(!a)return a;var f={},c;for(c in a)a.hasOwnProperty(c)&&(f[c]=b(a[c],c,a));return f},wa:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},Vb:function(b){b=a.a.Q(b);for(var c=w.createElement("div"),f=0,d=b.length;fh?a.setAttribute("selected",b):a.selected=b},la:function(a){return null===a||a=== -q?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},ec:function(b,c){for(var f=[],d=(b||"").split(c),e=0,g=d.length;ea.length?!1:a.substring(0,b.length)===b},Gb:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode; -return!!a},va:function(b){return a.a.Gb(b,b.ownerDocument.documentElement)},Ra:function(b){return!!a.a.Ua(b,a.a.va)},v:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},r:function(b,d,f){var e=h&&g[d];if(e||"undefined"==typeof u)if(e||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var s=function(a){f.call(b,a)},l="on"+d;b.attachEvent(l,s);a.a.C.ea(b,function(){b.detachEvent(l,s)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(d, -f,!1);else{if(c(b,d)){var n=f;f=function(a,b){var f=this.checked;b&&(this.checked=!0!==b.Ab);n.call(this,a);this.checked=f}}u(b).bind(d,f)}},da:function(a,b){if(!a||!a.nodeType)throw Error("element must be a DOM node when calling triggerEvent");if("undefined"!=typeof u){var f=[];c(a,b)&&f.push({Ab:a.checked});u(a).trigger(b,f)}else if("function"==typeof w.createEvent)if("function"==typeof a.dispatchEvent)f=w.createEvent(e[b]||"HTMLEvents"),f.initEvent(b,!0,!0,y,0,0,0,0,0,!1,!1,!1,!1,0,a),a.dispatchEvent(f); -else throw Error("The supplied element doesn't support dispatchEvent");else if("undefined"!=typeof a.fireEvent)c(a,b)&&(a.checked=!0!==a.checked),a.fireEvent("on"+b);else throw Error("Browser doesn't support triggering events");},c:function(b){return a.M(b)?b():b},Ha:function(b){return a.M(b)?b.t():b},ma:function(b,c,f){if(c){var d=/\S+/g,e=b.className.match(d)||[];a.a.n(c.match(d),function(b){a.a.V(e,b,f)});b.className=e.join(" ")}},Ma:function(b,c){var f=a.a.c(c);if(null===f||f===q)f="";var d=a.e.firstChild(b); -!d||3!=d.nodeType||a.e.nextSibling(d)?a.e.S(b,[w.createTextNode(f)]):d.data=f;a.a.Jb(b)},pb:function(a,b){a.name=b;if(7>=h)try{a.mergeAttributes(w.createElement(""),!1)}catch(f){}},Jb:function(a){9<=h&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Hb:function(a){if(h){var b=a.style.width;a.style.width=0;a.style.width=b}},Zb:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var f=[],d=b;d<=c;d++)f.push(d);return f},Q:function(a){for(var b=[],c=0,d=a.length;c< -d;c++)b.push(a[c]);return b},cc:6===h,dc:7===h,ja:h,ab:function(b,c){for(var f=a.a.Q(b.getElementsByTagName("input")).concat(a.a.Q(b.getElementsByTagName("textarea"))),d="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},e=[],g=f.length-1;0<=g;g--)d(f[g])&&e.push(f[g]);return e},Wb:function(b){return"string"==typeof b&&(b=a.a.la(b))?B&&B.parse?B.parse(b):(new Function("return "+b))():null},Na:function(b,c,f){if(!B||!B.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"); -return B.stringify(a.a.c(b),c,f)},Xb:function(c,d,f){f=f||{};var e=f.params||{},g=f.includeFields||this.$a,h=c;if("object"==typeof c&&"form"===a.a.v(c))for(var h=c.action,n=g.length-1;0<=n;n--)for(var r=a.a.ab(c,g[n]),v=r.length-1;0<=v;v--)e[r[v].name]=r[v].value;d=a.a.c(d);var t=w.createElement("form");t.style.display="none";t.action=h;t.method="post";for(var E in d)c=w.createElement("input"),c.name=E,c.value=a.a.Na(a.a.c(d[E])),t.appendChild(c);b(e,function(a,b){var c=w.createElement("input");c.name= -a;c.value=b;t.appendChild(c)});w.body.appendChild(t);f.submitter?f.submitter(t):t.submit();setTimeout(function(){t.parentNode.removeChild(t)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.n);a.b("utils.arrayFirst",a.a.Ua);a.b("utils.arrayFilter",a.a.ga);a.b("utils.arrayGetDistinctValues",a.a.Va);a.b("utils.arrayIndexOf",a.a.l);a.b("utils.arrayMap",a.a.ha);a.b("utils.arrayPushAll",a.a.X);a.b("utils.arrayRemoveItem",a.a.ia);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost", -a.a.$a);a.b("utils.getFormFields",a.a.ab);a.b("utils.peekObservable",a.a.Ha);a.b("utils.postJson",a.a.Xb);a.b("utils.parseJson",a.a.Wb);a.b("utils.registerEventHandler",a.a.r);a.b("utils.stringifyJson",a.a.Na);a.b("utils.range",a.a.Zb);a.b("utils.toggleDomNodeCssClass",a.a.ma);a.b("utils.triggerEvent",a.a.da);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.K);a.b("utils.addOrRemoveItem",a.a.V);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=function(a){var c= -this,d=Array.prototype.slice.call(arguments);a=d.shift();return function(){return c.apply(a,d.concat(Array.prototype.slice.call(arguments)))}});a.a.f=new function(){function a(b,h){var k=b[d];if(!k||"null"===k||!e[k]){if(!h)return q;k=b[d]="ko"+c++;e[k]={}}return e[k]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===q?q:e[d]},set:function(c,d,e){if(e!==q||a(c,!1)!==q)a(c,!0)[d]=e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},D:function(){return c++ + -d}}};a.b("utils.domData",a.a.f);a.b("utils.domData.clear",a.a.f.clear);a.a.C=new function(){function b(b,c){var e=a.a.f.get(b,d);e===q&&c&&(e=[],a.a.f.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),m=0;m",""]||!d.indexOf("",""]||(!d.indexOf("",""]||[0,"",""];b="ignored
"+d[1]+b+d[2]+"
";for("function"==typeof y.innerShiv?c.appendChild(y.innerShiv(b)):c.innerHTML=b;d[0]--;)c=c.lastChild;c=a.a.Q(c.lastChild.childNodes)}return c};a.a.Ka=function(b,c){a.a.wa(b);c=a.a.c(c);if(null!==c&&c!==q)if("string"!=typeof c&&(c=c.toString()),"undefined"!=typeof u)u(b).html(c);else for(var d=a.a.Fa(c),e=0;ec[0]?l+c[0]:c[0]),l);for(var l=1===n?l:Math.min(b+(c[1]||0),l),n=b+n-2,r=Math.max(l,n),v=2;bc;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.tb(b);return a.a.Na(b,c,d)};d.prototype={save:function(b,c){var d=a.a.l(this.keys,b);0<=d?this.Qa[d]=c:(this.keys.push(b),this.Qa.push(c))},get:function(b){b=a.a.l(this.keys,b);return 0<=b?this.Qa[b]:q}}})();a.b("toJS",a.tb);a.b("toJSON",a.toJSON);(function(){a.k={o:function(b){switch(a.a.v(b)){case "option":return!0=== -b.__ko__hasDomDataOptionValue__?a.a.f.get(b,a.d.options.Ea):7>=a.a.ja?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.k.o(b.options[b.selectedIndex]):q;default:return b.value}},na:function(b,c){switch(a.a.v(b)){case "option":switch(typeof c){case "string":a.a.f.set(b,a.d.options.Ea,q);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.f.set(b,a.d.options.Ea,c),b.__ko__hasDomDataOptionValue__= -!0,b.value="number"===typeof c?c:""}break;case "select":""===c&&(c=q);if(null===c||c===q)b.selectedIndex=-1;for(var d=b.options.length-1;0<=d;d--)if(a.k.o(b.options[d])==c){b.selectedIndex=d;break}1=n){k&&c.push(l?{key:k,value:l.join("")}:{unknown:k});k=l=n=0;continue}}else if(58===t){if(!l)continue}else if(47===t&&r&&1=a.a.ja&&c in M?(c=M[c],h?b.removeAttribute(c):b[c]=d):h||b.setAttribute(c, -d.toString());"name"===c&&a.a.pb(b,h?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,c,d){function e(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):b.value}function g(){var k=b.checked,g=s?e():k;if(l&&(!m||k)){var h=a.i.p(c);f?p!==g?(k&&(a.a.V(h,g,!0),a.a.V(h,p,!1)),p=g):a.a.V(h,g,k):a.g.oa(h,d,"checked",g,!0)}}function h(){var d=a.a.c(c());b.checked=f?0<=a.a.l(d,e()):k?d:e()===d}var k="checkbox"==b.type,m="radio"==b.type;if(k||m){var f=k&&a.a.c(c())instanceof -Array,p=f?e():q,s=m||f,l=!1;m&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.h(g,null,{I:b});a.a.r(b,"click",g);a.h(h,null,{I:b});l=!0}}};a.g.U.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());"object"==typeof d?a.a.K(d,function(c,d){d=a.a.c(d);a.a.ma(b,c,d)}):(d=String(d||""),a.a.ma(b,b.__ko__cssValue,!1),b.__ko__cssValue=d,a.a.ma(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());d&&b.disabled?b.removeAttribute("disabled"): -d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,g){var h=c()||{};a.a.K(h,function(k){"string"==typeof k&&a.a.r(b,k,function(b){var f,h=c()[k];if(h){try{var s=a.a.Q(arguments);e=g.$data;s.unshift(e);f=h.apply(e,s)}finally{!0!==f&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===d.get(k+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={hb:function(b){return function(){var c= -b(),d=a.a.Ha(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.J.Aa};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.J.Aa}}},init:function(b,c){return a.d.template.init(b,a.d.foreach.hb(c))},update:function(b,c,d,e,g){return a.d.template.update(b,a.d.foreach.hb(c),d,e,g)}};a.g.Y.foreach=!1;a.e.P.foreach=!0;a.d.hasfocus= -{init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var g=b.ownerDocument;if("activeElement"in g){var f;try{f=g.activeElement}catch(h){f=g.body}e=f===b}g=c();a.g.oa(g,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var g=e.bind(null,!0),h=e.bind(null,!1);a.a.r(b,"focus",g);a.a.r(b,"focusin",g);a.a.r(b,"blur",h);a.a.r(b,"focusout",h)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===d||(d?b.focus():b.blur(),a.i.p(a.a.da, -null,[b,d?"focusin":"focusout"]))}};a.g.U.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.g.U.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Ka(b,c())}};var L=a.a.f.D();H("if");H("ifnot",!1,!0);H("with",!0,!1,function(a,c){return a.createChildContext(c)});a.d.options={init:function(b){if("select"!==a.a.v(b))throw Error("options binding applies only to SELECT elements");for(;0a.a.ja?0:b.nodes)?b.nodes():null;if(c)return a.a.Q(c.cloneNode(!0).childNodes);b=b.text();return a.a.Fa(b)};a.J.Aa= -new a.J;a.La(a.J.Aa);a.b("nativeTemplateEngine",a.J);(function(){a.Ba=function(){var a=this.Rb=function(){if("undefined"==typeof u||!u.tmpl)return 0;try{if(0<=u.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,g){g=g||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=u.template(null,"{{ko_with $item.koBindingContext}}"+h+ -"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=u.extend({koBindingContext:e},g.templateOptions);e=u.tmpl(h,b,e);e.appendTo(w.createElement("div"));u.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){w.write("